[Boulder.pm] Trickey (for a newbie) String Replacement

Luke Palmer luke at luqui.org
Thu May 6 15:42:18 CDT 2004


Peter Hutnick writes:
> Rob Nagler wrote:
> 
> >Peter Hutnick writes:
> >
> >>   foreach $rule (@rules) {
> >>      $text =~ (eval $rule)
> >
> >
> >You could:
> >
> >    eval("$text =~ $rule");
> 
> This gives me:
> 
> Backslash found where operator expected at (eval 1) line 1, near "a \"
>         (Do you need to predeclare a?)
> 
> The first rule is "s/\\emph{(.*?)}/\<em\>$1\<\/em\>/g;" which works if I 
> just paste it in.

He meant:

    eval("\$text =~ $rule");

You don't want your text expanded and evaluated as Perl code.

I suggest operating on $_, however.  That way you can have multiple
statements in a rule if you like, without being horribly hackly.

> >This assumes a certain structure to $rule.  Alternatively, you could
> >use the $_ approach, that is, have the $rule assume a specific
> >variable name that contains the text, e.g., write the rules like:
> >
> >    '$text =~ s/\\\\bla/<bla>/',
> 
> Since TeX commands are in the form \bla I am confused about why you put 
> \\\\bla, not \\bla.

Well, look at the expansion.  When you have:

    $rx = 's/\\bla/<bla>/';

Then $rx contains the string:

    s/\bla/<bla>/

Since a double-backslash in a single quoted string turns into a single
backslash.  This is something that I dislike and am trying to change for
Perl 6, but no luck so far.

So now you're matching against a word boundary \b and then "la", which
isn't what you want. 

If you read the rules in from a file or use a single-quoted heredoc, you
don't run into that problem:

my @rules = split /^/, <<'EORULES';
s/\\bla/<bla>/g;    # works as expected
EORULES

Luke




More information about the Boulder-pm mailing list