Re: Store regular expressions in a file.
by BrowserUk (Patriarch) on Nov 11, 2010 at 10:46 UTC
|
You could eval the code into existence. People decry it, but it is one thing that makes dynamic languages so powerful:
#!/usr/bin/perl
use strict;
use warnings;
my $data = "duck";
while(<DATA>) {
chomp;
my $code = eval "sub{ \$_[0] =~ $_ }" // die $@;
if( $code->( $data ) ) {
print "$data\n";
}
}
__DATA__
s/duck/luck/
Produces: c:\test>junk02
luck
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
Re: Store regular expressions in a file.
by cdarke (Prior) on Nov 11, 2010 at 10:58 UTC
|
this 'data' is a regular expression
No, it is not a regular expression, only the duck is a regular expression. s is a Perl operator. If you can it would be a lot easier to have two columns, the first being the RE pattern ('duck') and the second being the replacement text ('luck') and then read them into variables (using split) - it is perfectly valid (and common) to store an RE in a Perl variable.
Otherwise you will be reduced to doing nasty things like eval, and you don't want to go there. | [reply] [d/l] |
|
So something like this? I don't get any output.
Thanks
#!/usr/bin/perl
use strict;
use warnings;
my $data = "duck";
my $r;
while(<DATA>) {
chomp;
my ($x, $y) = split(/\s/, $_);
$r->{$x} = qr/$y/;
if ($data =~ $r->{"duck"}) {
print "$data\n";
}
}
__DATA__
duck s/duck/luck/
| [reply] [d/l] |
|
| [reply] |
Re: Store regular expressions in a file.
by roboticus (Chancellor) on Nov 11, 2010 at 12:56 UTC
|
#!/usr/bin/perl
use strict;
use warnings;
# Read the regexes
my @Rexes;
while (my $t=<DATA>) {
chomp $t;
last if $t=~/^$/;
my ($regex, $repl) = split /\t+/, $t;
push @Rexes, [ qr($regex), $repl ];
}
# Process the text
while (my $l = <DATA>) {
$l=~s/$$_[0]/$$_[1]/eg for @Rexes;
print $l;
}
__DATA__
duck cluck
a(b+)c c$1a
That bird says "duck!"
xyzzy plugh ac abc abbc abbbc
It mostly works, but as you can see from the following run, I haven't been able to make back references work...
roboticus@Boink:~
$ perl pm870806_dyn_regex.pl
That bird says "cluck!"
xyzzy plugh ac c$1a c$1a c$1a
...roboticus
| [reply] [d/l] [select] |
|
#!/usr/local/bin/perl
use strict;
use warnings;
use String::Interpolate qw(safe_interpolate);
# Read the regexes
my @Rexes;
while (my $t = <DATA>) {
chomp $t;
last if $t =~ /^$/;
my ($regex, $repl) = split /\t+/, $t;
push @Rexes, [ qr($regex), $repl ];
}
# Process the text
while (my $l = <DATA>) {
$l=~ s/$$_[0]/safe_interpolate($$_[1])/eg for @Rexes;
print $l, "\n";
}
__DATA__
duck cluck
a(b+)c \uc${1}\ua
That bird says "duck!"
xyzzy plugh ac abc abbc abbbc
That bird says "cluck!"
xyzzy plugh ac CbA CbbA CbbbA
| [reply] [d/l] [select] |
|
| [reply] |
|
Thanks everyone for the enlightenment!!
| [reply] |
Re: Store regular expressions in a file.
by mjscott2702 (Pilgrim) on Nov 11, 2010 at 11:42 UTC
|
If you just wanted to create regular expressions for matching from a file, you could use the qr quoting operator, but don't think that will work for substituting as you appear to want to do - as others have pointed out, you would probably have to use eval for that. | [reply] [d/l] [select] |
|
| [reply] |
|
#!/usr/bin/perl
use strict;
use warnings;
my $data = "duck";
while(<DATA>) {
chomp;
my( $find, $replace ) = split ' ', $_, 2;
if( $data =~ s[\Q$find][$replace]e ) {
print "$data\n";
}
}
__DATA__
duck luck
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: Store regular expressions in a file.
by sundialsvc4 (Abbot) on Nov 11, 2010 at 12:08 UTC
|
The magic voodoo you are looking for is: qr/some_expression/.
This operator compiles a regular expression that is made from some_string.
When constructing the string, be careful: you might be tempted to use interpolation (double-quotes...) but this will cause the “rabbit-food” of the regex syntax itself to be turned into escape-characters.
Furthermore, you might find that you can successfully put a string-variable reference into the regular expression string (i.e. without using qr//), and find that it is properly interpolated. If you simply want to substitute “a particular string to search for” into an otherwise-fixed expression, this is one way to do that.
If the regexes to be used are truly arbitrary, however, you will want to use qr//, and to enclose that statement in an eval block to trap runtime errors caused by invalid regex syntax.
| |
Re: Store regular expressions in a file.
by JavaFan (Canon) on Nov 11, 2010 at 10:48 UTC
|
I'd like to read a bunch of regular expressions from a flat text for use in a script. After I read the file, how do I tell Perl thats this 'data' is a regular expression?
Replace "regular expression" with "number", and ask yourself the same question. How does Perl do that?
| [reply] |