2012-04-18 71 views
6

我想回答this question權威的正則表達式(S)格式化字符串

要獲得所有Perl的別緻的格式鍵訪問的散列數據,你 需要(更好的版本的這個)功能:

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

但我很害羞的風險/暴力方法來捕獲格式字符串的'尾巴'。

所以:有格式字符串,你可以信任的正則表達式?

+0

您是否知道''%%'在'sprintf'中不是特例?例如'sprintf('%2%')'會產生字符串''%''。 – 2012-04-18 19:59:33

回答

0

的可接受的格式是很好在perldoc -f sprintf speced出來。在'%'和格式字母之間,你可以有:

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

問題是某些修飾符只適用於某些格式說明符。 – 2012-04-18 20:48:45

+0

的OP只是路過的格式標記到內置'sprintf',不是要重新實現'sprintf'。如果輸入包含無效序列,那麼它的處理方式與Perl的'sprintf'處理它相同,這可能是所需的行爲。 – mob 2012-04-18 21:22:38

+0

例如,'sprintfx「%(abc)vs」,{abc =>「def」};'be?它應該是'%(abc)vs'還是可以接受爲'%vs'? – mob 2012-04-18 21:24:59

1

如果你問如何做到這一點酷似Perl中,然後諮詢的Perl做什麼。

Perl_sv_vcatpvfnsprintf格式的分析和評估。 (鏈接到5.14.2的實現。)