Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Generating patterns 1

Status
Not open for further replies.

jimshew

MIS
Feb 10, 2004
10
0
0
US
Hey all,
I'm trying to load a list of strings to match on into an array and then do an

if($content =~ /$matchlist[$i]/ || /$matchlist[$i+1]) ....

It is necessary that I have one big atomic match in this if statement, I can't wrap it in a for loop.

Anyways, I'm having a hard time trying to use qr// to build this statement and have it parsed as an expression. The O'Reilly example on "Generating patterns" with the VVCVV seems to not be exactly what I'm looking for.

Does anybody know of a better example to build a list of regexs in the script, then using it as the if statement later? I'm having a hard time finding any examples or info on this.


 
How about
Code:
if (grep {$content =~ $_} @matchlist)

Will eval to true if $content matches any expression in @matchlist.
 
That's the sort of thing I was looking for. Only this doesn't match anything (earlier, I had it matching on everything somehow).

With your example, do I need to qr// each item in @matchlist when I build the array?

Also, I neglected to mention, that the @matchlist only has a substring:

$content1 = "The quick brown fox\n";
$content2 = "The slow red fox\n";
@matchlist = ("quick","red fox");

would return true for each content test. I had a feeling I was making it more complicated than it needed to be. Thanks again for any help, I haven't tried to do this with Perl before.
 
Turn it around, like so:
Code:
if (grep {$_ =~ /$content/} @matchlist)
When I've done similar things, I've enclosed each re in the list in single quotes so I didn't need to escape special characters. I haven't used qr//.
 
Ok, I think I've been at this too long. Your first one was correct! I got bit by case sensitivity. What would be the "best" way to add a /i equivalent on the match? can I store it in @matchlist or do I need to make $_ a /$_/

I just want the least confusing, because next time I have to revisit this, I don't want to be too lost! Thanks again, you had a simple answer, and that was what I was hoping for, I knew the Camel book in all its glory had a too complicated example to try and copy.
 
Put $_ in delimiters and use the i modifier:
Code:
if (grep {$content =~ /$_/i} @matchlist)
 
Meant to put this in my last post but was having problems with my computer and had to shut down:

Now that you've found something that works, you probably won't want to change, but it really would be much more efficient to use a loop to search @matchlist for a match and set a flag and exit if and when one is found, rather than to use grep. Grep will always search the whole list, even if it finds a match on the first element. Very inefficient, obviously.

You could use a small loop like this, which will exit as soon as a match is found
Code:
my ($found, $i) = (0, 0);
while ($i < @matchlist && !$found) {
    $found = ($content =~ /$matchlist[$i++]/i);
}
Then, where you're currently using grep:
Code:
 if ($found) {
This would really be a better way to go, especially if @matchlist is long. I suggested grep because you said you couldn't use a &quot;for&quot; loop, but then it occurred to me that you may not have been thinking in terms of &quot;set a flag and exit&quot;. A while loop lends itself to this more readily.
 
Thanks for the extra tip. My matchlist shouldn't be more than 20 strings.

This looks like it will work, I'll save it in case this script ends up parsing more than this small list. The use of the script is only once a day to scan a report, so in my use, I'll be fine with the grep.

But hey, like I said, I couldn't find any working examples, and you gave me a few and helped me learn something in Perl.

The funny thing about Perl (ok, _one_ of them) is that since there's more than one way to do it, I usually end up doing it the old way that isn't the best (ok, that's arguable, I know). Now I actually learned something. Thanks again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top