Re: How to apply modifiers to a substitution via variable?
by GrandFather (Saint) on Jan 31, 2007 at 22:26 UTC
|
use strict;
use warnings;
my $string = "aaaaaaaaa";
my $modifiers = "g";
eval "\$string =~ s/a/b/$modifiers;";
print $string;
Update: note that only question 1 was answered because only question 1 was asked at the time of posting. OP performed a substantive silent update subsequent to the initial create.
DWIM is Perl's answer to Gödel
| [reply] [d/l] |
Re: How to apply modifiers to a substitution via variable?
by ikegami (Patriarch) on Jan 31, 2007 at 23:50 UTC
|
I find the suggestions to use eval EXPR unwise and suggestions to use s///ee (eval EXPR's disguised form) deplorable. Don't generate code for eval that you can't easily validate. Fortunately, eval EXPR is not needed. Here's a copy of my earlier answer to the same question.
For imsx, you can use (?switches:pattern). For g, you'll have to use an if.
my $source = "abc";
my $find = "a";
my $replace = "x";
my %opts = (
i => 1,
m => 0,
s => 0,
x => 0,
g => 1,
);
my $opts = join '', map { $opts{$_}?$_:'' } qw( i m s x );
my $re = "(?$opts:$find)";
if ($opts{g}) {
$source =~ s/$re/$replace/g;
} else {
$source =~ s/$re/$replace/;
}
print $source;
Update: Fixed where %opts was referenced as %opt.
| [reply] [d/l] [select] |
|
|
Except that, since you didn't use strict or warnings, which IMO is just as "deplorable" as using eval, you've got a hidden error:
use strict;
use warnings;
my $source = "abc";
my $find = "a";
my $replace = "x";
my %opts = (
i => 1,
m => 0,
s => 0,
x => 0,
g => 1,
);
my $opts = join '', map { $opt{$_}?$_:'' } qw( i m s x );
my $re = "(?$opts:$find)";
if ($opt{g}) {
$source =~ s/$re/$replace/g;
} else {
$source =~ s/$re/$replace/;
}
print $source;
s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
| [reply] [d/l] [select] |
|
|
Global symbol "%opt" requires explicit package name at test.pl line 16
+.
Global symbol "%opt" requires explicit package name at test.pl line 19
+.
Execution of test.pl aborted due to compilation errors
Update: To clarify a bit ... I don't really think that skipping use strict; and use warnings; is "deplorable". But I also don't think that sometimes using eval or the /e modifier to a regular expression is, either. ;-)
s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
| [reply] [d/l] [select] |
|
|
I didn't say it was tested code. And it's just a snippet to be inserted into a larger program with use strict and use warnings.
And I didn't say /e (which is harmless), but /ee. If you're going to execute untrusted code, at least make it obvious. Don't hide it!
| [reply] [d/l] [select] |
Re: How to apply modifiers to a substitution via variable?
by jettero (Monsignor) on Jan 31, 2007 at 22:30 UTC
|
my $string = "aaaaaaaaa";
$modifiers = "g";
$string =~ s/(?$modifiers:a)/b/; # ??
print $string;
Although, the more I think about it... I don't think /g in there. /i does.
For that second question, though, I think you'll have to eval like the post above.
| [reply] [d/l] [select] |
Re: How to apply modifiers to a substitution via variable?
by liverpole (Monsignor) on Jan 31, 2007 at 22:38 UTC
|
Hi lokiloki,
Grandfather's answered your first question already.
In answer to your second, you can use eval for this as well, but make sure you put apostrophes (') around the $1 in the assignment, rather than quotes ("), or you'll get an error. Here's the code:
#!/usr/bin/perl
use strict;
use warnings;
my $string = "aaaaabbbbaaaaaa";
my $replace = '$1';
eval "\$string =~ s/a+(b+)a+/$replace/g";
print $string;
bbbb
Note that you need to use quotes (") around the eval statement so that $1 will interpolate, but (as Grandfather did) you still have to escape $string with the backslash "\" in the same line (\$string), so it won't interpolate.
s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
| [reply] [d/l] [select] |
Re: How to apply modifiers to a substitution via variable?
by GrandFather (Saint) on Jan 31, 2007 at 22:51 UTC
|
For the second issue generally /e (evaluate) is used, but you need it twice. Remember to quote the $ in the string for $replace, or use single quotes so Perl doesn't try to interpolate $1:
my $replace = '$1';
$string =~ s/a+(b+)a+/$replace/eeg;
DWIM is Perl's answer to Gödel
| [reply] [d/l] |
Re: How to apply modifiers to a substitution via variable?
by johngg (Canon) on Jan 31, 2007 at 22:53 UTC
|
You can do the second part without an eval but with an ee modifier, like this
$ perl -le '
> $str = q{aaabbbaaa};
> $repl = q{$1};
> $str =~ s{a+(b+)a+}{$repl}ee;
> print $str;'
bbb
$
The first e executes the $repl resulting in $1, the second e executes the $1 resulting in whatever was captured, "bbb" here.
Cheers, JohnGG | [reply] [d/l] [select] |