I'd like to replace $ characters with $$ unless $ is followed by one of ^
, @
, (
, or $
.
For example given:
$(bar) $@ $$.z $^.zh $(foo) $foo $bar
I'd like:
$(bar) $@ $$.z $^.zh $(foo) $$foo $$bar
I have a brutal hack way of doing this (replacing the patterns I don't want to get modified with a temporary probably unique garbage sequence), replacing everything left, and then undoing my temporaries.
my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';
my $d = '$';
my $at = '@';
$var =~ s/\$\(/<<<<DDDDBBBB>>>>/g;
$var =~ s/\$\@/<<<<DDDDAAAA>>>>/g;
$var =~ s/\$\^/<<<<DDDDCCCC>>>>/g;
$var =~ s/\$\$/<<<<DDDDDDDD>>>>/g;
$var =~ s/\$/$d$d/g;
$var =~ s/<<<<DDDDBBBB>>>>/$d(/g;
$var =~ s/<<<<DDDDAAAA>>>>/$d$at/g;
$var =~ s/<<<<DDDDCCCC>>>>/$d^/g;
$var =~ s/<<<<DDDDDDDD>>>>/$d$d/g;
print "$var\n";
This works, but it's butt ugly. My naive one liner attempt was:
my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';
print "$var\n";
my $d = '$';
$var =~ s/\$([^\@\(\$\^])/$d$d$1/g;
print "$var\n";
but this does not handle the $$ correctly. The first match of $$ fails to replace as desired, but the '$.' part of '$$.' character sequence gets replaced, giving:
$(bar) $@ $$$.z $^.zh $(foo) $$foo $$bar
I could do a hybrid:
my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';
my $d = '$';
my $at = '@';
print "$var\n";
$var =~ s/\$\$/<<<<DDDDDDDD>>>>/g;
$var =~ s/\$([^\@\(\^])/$d$d$1/g;
$var =~ s/<<<<DDDDDDDD>>>>/$d$d/g;
print "$var\n";
but that's still ugly, just not quite so bad. Is there a way of doing this replacement with a single perl regex, perhaps using assertions or lookarounds?
CodePudding user response:
I'd like to replace $ characters with $$ unless $ is followed by one of ^, @, (, or $.
Use a look ahead.
s/ \$ (?! [\^\@(\$] ) / '$$' /xeg
but this does not handle the $$ correctly.
It does according to what you said you wanted.
But you appear appear to have an unstated requirement to ignore $
characters if the number of $
characters immediately preceding it is odd.
An easy way to handle that is by simply replacing $$
in addition to $
not followed by ^
/@
/)
.
s/ \$ (?: \$ | (?! [\^\@\(] ) ) / '$$' /xeg