Monday, December 29, 2014

Perl Regular Expression Capture Groups

After cursing Bedrock for not giving me access to capture groups in regular expressions, I finally bit the bullet and figured out how to implement this in a somewhat sane manner.


Consider:

<if $path_info --re '/customer/\\d+$'>
...do something useful with the digits?
  <null:uri $path_info.split('/')>
  <null:id $uri.[2]>
</if>

The test above looks for one or more digits after the string '/customer/'.  

Note that Bedrock regular expressions in a --re expression require that you escape the slash but they do not require any delimiters at either end of the regular expression.  You can also use Perl's quote-like operator qr// in order to specify a regular expression used with --re.  The quote-like operator is useful when specifying options (like case insensitive matching) with your regular expressions (qr/\\/customer\\/\\d+$/i).

Of course what we would probably like to do instead of having to decompose the URI is to simply capture the digits in the regular expression with something that looks like this:

<if $path_info --re '/customer/(\\d+)$'>
...do something useful with the digits?
  <null:id $1>
</if>

..but alas Bedrock a) does not allow a numeric digit after the sigil as a variable name and b) does not expose the values of capture groups...until now.

Perl 5.10 introduced named capture groups, so we might be able to do something like this:

<if $path_info --re '/customer/(?<id>\\d+)$'>
...do something useful with the digits?
</if>

..and in fact we can, almost.  Just one more tweak...the '>' character in the expression needs to be escaped.

<if $path_info --re '/customer/(?<id\>\\d+)$'>
...do something useful with the digits?
</if>

Cool! Now we have access to $id as the named capture value in Bedrock 2.4.1-7.  A tweak to the expression parser (TagX::Expr) and the <if> tag did the trick.

Sometimes adding programming features to a templating package like Bedrock feels like teaching my dog to sing Jingle Bells.  It's interesting, it keeps me amused and in the end it sort of works, but it's still a dog singing Jingle Bells.  ;-)

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.