in reply to Regexp::Common balanced curlies substitution
Note that the placeholder strings in the replacement pattern specifier taken from the file are changed to $tag and $body from the, to my mind, more fragile $2 and $1.
Getting rid of $inpattern and inlining its pattern elements in the substitution regex is, to me, desirable because it puts regex captures 'closer' to the point at which they are used. (The example code works the same either way.)
BTW: This would probably be a nice place to use 5.10 named captures.
use warnings; use strict; use Regexp::Common; my $text = q{start \chapter{argument1}{argument2} end}; print "INPUT: '$text' \n"; # macro name and replacement pattern taken from a file, sans newlines. chomp(my $macro_name = <DATA>); chomp(my $replacement_pattern = <DATA>); my $parens = '{}'; my $arg = qr{ $RE{balanced}{-parens => $parens} }xms; my $intro = qr{ \\ }xms; my $inpattern = qr{ $intro $macro_name \s* ($arg) \s* ($arg) }xms; # print "inpattern $inpattern \n"; # FOR DEBUG $text =~ # s{ $inpattern } s{ $intro $macro_name \s* ($arg) \s* ($arg) } { my ($body, $tag) = ($1, $2); # nail down captures soonest validate_paired($parens, $body, $tag); trim_paired ($parens, $body, $tag); eval qq{ qq{$replacement_pattern} } or die "replacement failed: '$replacement_pattern'"; }xmsge; print "OUTPUT: '$text' \n"; print "\n"; sub trim_paired { my $pair = shift; # opening/closing pair of chars to trim my ($opener, $closer) = $pair =~ m{ \S }xmsg; die "pair of opening and closing chars not supplied: $pair" unless defined $opener and defined $closer; s{ \A $opener | $closer \z }''xmsg for @_; } sub validate_paired { my $pair = shift; # opening/closing pair of bracing chars my ($opener, $closer) = $pair =~ m{ \S }xmsg; die "pair of opening and closing chars not supplied" unless defined $opener and defined $closer; m{ \A $opener .* $closer \z }xms or die "not braced: '$_'" for @_; } __DATA__ chapter <h1 tag="$tag">$body</h1>
Output (both with and without $inpattern):
INPUT: 'start \chapter{argument1}{argument2} end' OUTPUT: 'start <h1 tag="argument2">argument1</h1> end'
|
|---|