2012-04-18 16 views
6

me gustaría responder this question conexpresión regular autorizada (s) printf formato de cadena

Para obtener todos los formato de lujo de Perl y acceso con clave para cifrar datos, necesita un (mejor versión de este) función:

# sprintfx(FORMAT, HASHREF) - like sprintf(FORMAT, LIST) but accepts 
# "%<key>$<tail>" instead of "%<index>$<tail>" in FORMAT to access the 
# values of HASHREF according to <key>. Fancy formatting is done by 
# passing '%<tail>', <corresponding value> to sprintf. 
sub sprintfx { 
    my ($f, $rh) = @_; 
    $f =~ s/ 
    (%%)    # $1: '%%' for '%' 
    |     # OR 
    %     # start format 
    (\w+)    # $2: a key to access the HASHREF 
    \$     # end key/index 
    (     # $3: a valid FORMAT tail 
         # 'everything' upto the type letter 
     [^BDEFGOUXbcdefginosux]* 
         # the type letter ('p' removed; no 'next' pos for storage) 
     [BDEFGOUXbcdefginosux] 
    ) 
    /$1 ? '%'       # got '%%', replace with '%' 
     : sprintf('%' . $3, $rh->{$2}) # else, apply sprintf 
    /xge; 
    return $f; 
} 

pero me da vergüenza del método de fuerza arriesgada/bruta para la captura de la cadena de formato 'cola'.

Entonces: ¿Hay una expresión regular para la cadena FORMAT en la que puede confiar?

+0

¿Sabía que '%%' no es un caso especial en 'sprintf'? Por ejemplo, 'sprintf ('% 2%')' produciría la cadena ''%''. –

Respuesta

0

El formato aceptable está muy bien especificado en perldoc -f sprintf. Entre el '%' y la letra formato, puede tener:

 (\d+\$)?   # format parameter index (though this is probably 
         # incompatible with the dictionary feature) 

    [ +0#-]*   # flags 

    (\*?v)?   # vector flag 

    \d*    # minimum width 

    (\.\d+|\.\*)? # precision or maximum width 

    (ll|[lhqL])?  # size 
+0

El problema es que algunos modificadores solo se aplican a algunos especificadores de formato. –

+0

El OP acaba de pasar los tokens de formato al 'sprintf' incorporado, sin tratar de volver a implementar' sprintf'. Si la entrada contiene una secuencia inválida, se manejará de la misma manera que la 'sprintf' de Perl lo manejaría, que podría ser el comportamiento deseado. – mob

+0

por ejemplo, ¿Cuál debería ser la salida de 'sprintfx"% (abc) vs ", {abc =>" def "};' ser? ¿Debería ser '% (abc) vs' o es aceptable que sea'% vs'? – mob

1

Si estás preguntando cómo hacerlo exactamente como Perl, a continuación, consulte lo que hace Perl.

Perl_sv_vcatpvfn es sprintf analizador de formato y evaluador. (Enlace a la implementación de 5.14.2.)

Cuestiones relacionadas