2012-04-18 13 views
6

Vorrei rispondere this question conautorevole espressione regolare per (s) FORMATO printf stringa

Per ottenere tutte le fantasia formattazione di Perl e accesso con chiave di hash dei dati, è bisogno di una (versione migliore di questo) funzione:

# 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; 
} 

ma mi vergogno di un approccio rischioso/forza bruta alla cattura della stringa di formato 'coda'.

Quindi: Esiste un'espressione regolare per la stringa FORMAT di cui ci si può fidare?

+0

Sei consapevole che '%%' non è un caso speciale in 'sprintf'? Ad esempio 'sprintf ('% 2%')' produrrebbe la stringa ''%''. –

risposta

0

Il formato accettabile è abbastanza ben definito in perldoc -f sprintf. Tra il '%' e la lettera formato, è possibile avere:

 (\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

Il problema è che alcuni modificatori si applicano solo ad alcuni specificatori di formato. –

+0

L'OP sta passando i token di formato allo 'sprintf' incorporato, non sta provando a reimplementare' sprintf'. Se l'input contiene una sequenza non valida, verrà gestita allo stesso modo che lo 'sprintf' di Perl lo gestirà, il che potrebbe essere il comportamento desiderato. – mob

+0

ad es., Quale dovrebbe essere l'output di 'sprintfx"% (abc) vs ", {abc =>" def "};' be? Dovrebbe essere '% (abc) vs' o è accettabile che sia'% vs'? – mob

1

Se stai chiedendo come si fa esattamente come Perl, quindi consultare quello che fa Perl.

Perl_sv_vcatpvfn è il parser e il valutatore di formato sprintf. (Collegamento all'implementazione 5.14.2.)

Problemi correlati