regex trick needed

P

Patrick Drouin

Hello guys,

I've browsed the web, looked at the camel book and asked around but I
haven't been able to solve what seems to be a simple problem. I want to
load regex on the fly from an external file, that's not a big thing.

The problem I am running into is that these regex used patterns I have
described somewhere else in my program and stored into scalars. Here's
the thing :

Defined in my program (to simplify regex writing by the users):
$nom = '[^\/]+\/(?:proper|Common)_Noun\/[^ ]+';
$adj = '[^\/]+\/Adjective\/[^ ]+';
.....

I now have these rules outside:
\s$nom
\s$nom (?:$adj)+

I use them this way :
if(@matches = $line =~ /$regex/g) {save_list(@matches);print "Yup!\n";}
else {print "Nope!\n";}

I'm not getting any "Yup!" back.... It seems that the internal $nom
scalar is not expanded to its definition in the pattern. Is there anyway
to force Perl to do this in a regex?

I've tried defining the first rule as this in the external file and it
works just fine :

\s[^\/]+\/(?:proper|Common)_Noun\/[^ ]+

Any help will be appreciated.

Patrick
 
P

Paul Lalli

I've browsed the web, looked at the camel book and asked around but I
haven't been able to solve what seems to be a simple problem. I want to
load regex on the fly from an external file, that's not a big thing.

The problem I am running into is that these regex used patterns I have
described somewhere else in my program and stored into scalars. Here's
the thing :

Defined in my program (to simplify regex writing by the users):
$nom = '[^\/]+\/(?:proper|Common)_Noun\/[^ ]+';
$adj = '[^\/]+\/Adjective\/[^ ]+';
....

I now have these rules outside:
\s$nom
\s$nom (?:$adj)+

I use them this way :
if(@matches = $line =~ /$regex/g) {save_list(@matches);print "Yup!\n";}
else {print "Nope!\n";}

I'm not getting any "Yup!" back.... It seems that the internal $nom
scalar is not expanded to its definition in the pattern. Is there anyway
to force Perl to do this in a regex?

I can't parse most of what you've said (and you didn't provide a
short-but-complete script that demonstrates your problem), but this
sentence is a red-flag. Have you read the entry titled "How can I
expand variables in text strings?" in the Perl FAQ?

perldoc -q expand

If that doesn't solve your problem, please post a short-but-complete
script that demonstrates your problem. Perl is usually easier to
understand than English. (of course, the best explanation is both Perl
and English...)

Paul Lalli
 
M

Matija Papec

X-Ftn-To: Patrick Drouin

Patrick Drouin said:
Defined in my program (to simplify regex writing by the users):
$nom = '[^\/]+\/(?:proper|Common)_Noun\/[^ ]+';
$adj = '[^\/]+\/Adjective\/[^ ]+';
....

I now have these rules outside:
\s$nom
\s$nom (?:$adj)+

I use them this way :
if(@matches = $line =~ /$regex/g) {save_list(@matches);print "Yup!\n";}
else {print "Nope!\n";}

I'm not getting any "Yup!" back.... It seems that the internal $nom

I would first print $line and $regex before your condition.
 
G

Gunnar Hjalmarsson

Patrick said:
Defined in my program (to simplify regex writing by the users):
$nom = '[^\/]+\/(?:proper|Common)_Noun\/[^ ]+';
$adj = '[^\/]+\/Adjective\/[^ ]+';
....

I now have these rules outside:
\s$nom
\s$nom (?:$adj)+

I use them this way :
if(@matches = $line =~ /$regex/g) {save_list(@matches);print "Yup!\n";}
else {print "Nope!\n";}

I'm not getting any "Yup!" back.... It seems that the internal $nom
scalar is not expanded to its definition in the pattern. Is there anyway
to force Perl to do this in a regex?

Maybe you want to preprocess $regex before using it in the regex.

perldoc -q "expand variables"

If that doesn't help, please post a short but *complete* program that
illustrates what you are trying to do.
 
P

Patrick Drouin

Although the description of my problem was not very clear, you guys
pointed me in the right direction. Here's what I used:

$rule =~ s/\$(\w+)/${$1}/g;

This expans the variable used inside the rule I read from text files.

Thanks,
Patrick
 
B

Ben Morrow

Quoth (e-mail address removed):
Although the description of my problem was not very clear, you guys
pointed me in the right direction. Here's what I used:

$rule =~ s/\$(\w+)/${$1}/g;

This expans the variable used inside the rule I read from text files.

Gah, yuck!

Why haven't you got strictures on?

Use a hash of common patterns instead:

my %Patterns = (
pnoun => qr/(?:Common\s+)Noun/,
);

my $rule = get_rule_from_file;

$rule =~ s/\$(\w+)/$Patterns{$1}/g;

And if you're going to be matching these a lot, it's probably worth
compiling them:

$rule = qr/$rule/;

Ben
 
G

Gunnar Hjalmarsson

Patrick said:
Although the description of my problem was not very clear, you guys
pointed me in the right direction. Here's what I used:

$rule =~ s/\$(\w+)/${$1}/g;

This expans the variable used inside the rule I read from text files.

If that made it, you are probably not using strict. Bad! :(

A better solution is indicated at the *end* of

perldoc -q "expand variables"

Why not try that, and start using strictures and warnings, and become a
better Perl programmer? ;-)
 
T

Tad McClellan

Patrick Drouin said:
Although the description of my problem was not very clear, you guys
pointed me in the right direction. Here's what I used:

$rule =~ s/\$(\w+)/${$1}/g;


You should put "use strict;" in all of your Perl programs!
 
A

Arndt Jonasson

Tad McClellan said:
You should put "use strict;" in all of your Perl programs!

Sorry for being dense, but what would "use strict" complain about in
the above statement? Putting it inside a plausible-looking function
gave me no warnings at all. Placing it as the only statement in a file
gave me

"Global symbol "$rule" requires explicit package name at ./foo.pl line 9 (#1)".

Is that what you meant?
 
T

Tad McClellan

Arndt Jonasson said:
Sorry for being dense, but what would "use strict" complain about in
the above statement?


It uses Symbolic References.

Putting it inside a plausible-looking function
gave me no warnings at all. Placing it as the only statement in a file
gave me

"Global symbol "$rule" requires explicit package name at ./foo.pl line 9 (#1)".

Is that what you meant?


It would be a runtime error:

Can't use string ("foo") as a SCALAR ref while "strict refs" in use at ...

----------------
#!/usr/bin/perl
use warnings;
use strict;

our $foo = 'FOO';
my $rule = '$foo bar';
$rule =~ s/\$(\w+)/${$1}/g;
print "$rule\n";
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top