I would like to answer this question with
To get all of Perl's fancy formatting and keyed access to hash data, you need a (better version of this) function:
# 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;
}
but I'm ashamed of the risky/brute force approach to capturing the format string's 'tail'.
So: Is there a regular expression for the FORMAT string that you can trust?
The acceptable format is pretty well speced out in perldoc -f sprintf. Between the '%' and the format letter, you can have:
     (\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
                        If you're asking how to do it exactly like Perl, then consult what Perl does.
Perl_sv_vcatpvfn is sprintf format parser and evaluator. (Link to 5.14.2's implementation.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With