(s)printf FORMAT字符串的权威正则表达式

时间:2012-04-18 19:15:13

标签: regex perl printf

我想用

回答this question

要获得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;
}

但我对捕获格式字符串'尾'的冒险/暴力方法感到羞耻。

那么:您可以信任的FORMAT字符串是否有正则表达式?

2 个答案:

答案 0 :(得分:1)

如果您正在询问如何与Perl完全一样,那么请参考Perl所做的事情。

Perl_sv_vcatpvfnsprintf格式解析器和评估程序。 (链接到5.14.2的实现。)

答案 1 :(得分:0)

可接受的格式在perldoc -f sprintf中非常明确。在'%'和格式字母之间,您可以:

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