Beefy Boxes and Bandwidth Generously Provided by pair Networks kudra
laziness, impatience, and hubris
 
PerlMonks  

Rematching within a regular expression

by jeff987 (Initiate)
on May 11, 2012 at 22:11 UTC ( #970111=perlquestion: print w/ replies, xml ) Need Help??
jeff987 has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use a regular expression to extract text from a large number of .txt files. I have phrases that demarcate the beginning and ending of the piece of text I want to extract. However these phrases are potentially in other parts of the document as well. The specific problem I am trying to tackle is when the beginning phrase is repeated twice without the ending phrase occurring. This leads me to collect more of the text than I want. Hopefully this specific example will help explain my problem.

When I run this code:

$x = "dog 789 cat dog dog bird cat wonder dog frog cat"; @finds = ($x =~ /((?:dog)(?:.*?)(?:cat))/g);

I end up with:

$finds[0] = dog 789 cat $finds[1] = dog dog bird cat $finds[2] = dog frog cat

How do I change my regular expression to skip over the second "dog" and end up with $finds[1] = dog bird cat?

Thanks in advance! Please excuse me if I have broken any protocols. I'm quite new to Perl and this is my first time seeking help here.

Comment on Rematching within a regular expression
Select or Download Code
Re: Rematching within a regular expression
by sauoq (Abbot) on May 11, 2012 at 23:46 UTC

    This may or may not be good in your case...

    #!/usr/bin/perl -l $x = "dog 789 cat dog dog bird cat wonder dog frog cat"; @finds = ($x =~ /((?:dog)(?:.*?)(?:cat))/g); $y = reverse $x; @finds2 = ($y =~ /((?:tac)(?:.*?)(?:god))/g); print for @finds; print "-----"; print scalar reverse for reverse @finds2;

    Ouptuts:

    dog 789 cat dog dog bird cat dog frog cat ----- dog 789 cat dog bird cat dog frog cat

    It's a nice technique to know, anyway. (The credit goes to japhy for it.)

    -sauoq
    "My two cents aren't worth a dime.";
Re: Rematching within a regular expression
by Anonymous Monk on May 12, 2012 at 03:24 UTC
    Use a negative look-ahead:
    $_ = "dog 789 cat dog dog bird cat wonder dog frog cat"; my @finds = /(dog(?:(?!dog).)*?cat)/g; say Dumper \@finds;
    Outputs:
    [ "dog 789 cat", "dog bird cat", "dog frog cat" ]

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://970111]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (12)
As of 2013-05-25 00:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best material for plates (tableware) is:









    Results (516 votes), past polls