Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

How do I extract the data that comes after a certain word?

by MiriamH (Novice)
on Jun 18, 2012 at 19:29 UTC ( #976880=perlquestion: print w/replies, xml ) Need Help??
MiriamH has asked for the wisdom of the Perl Monks concerning the following question:

I only want to print the words `yesterday and the day after`. I tried two ways, neither worked:
$String = "hello I went to the store yesterday and the day after and +the day after"; if ($String =~ /yesterday/i) { until ($String =~ /after/i) { print "Summary: $'" } }
This printed the entire string. I used the $' function, but it took too much data. How do I limit it?

Replies are listed 'Best First'.
Re: How do I extract the data that comes after a certain word?
by ikegami (Pope) on Jun 18, 2012 at 19:55 UTC

    First, previous answers use `$1`, but I hate using global variables when it's not necessary. It's not necessary here.

    Second, previous answers assume you don't want to capture newlines, but you didn't say anything of the kind.

    Fix:

    if (my ($match) = $s =~ /yesterday (.*?) after/s) { say $match; }

    Finally, using the `?` greediness modifier can lead to surprises (especially if you use more than one in a single pattern). If given

    yesterday foo yesterday bar after

    the above regex will capture

    foo yesterday bar

    If you want

    bar

    use the following instead:

    if (my ($match) = $s =~ /hello ((?:(?!yesterday).)*) yesterday/s) { say $match; }

    (?:(?!STRING).) is to STRING as [^CHAR] is to CHAR.

Re: How do I extract the data that comes after a certain word?
by tobyink (Abbot) on Jun 18, 2012 at 19:34 UTC

    This is probably the simplest way...

    my $String = "hello I went to the store yesterday and the day after an +d the day after"; if ($String =~ m{yesterday .+? after}) { print $&; }

    perlvar warns though that use of $& can slow down your script considerably. If it's a small script and raw speed is not your prime concern, this is probably acceptable. If performance does become a concern though, the following should also do the trick and is almost as readable...

    my $String = "hello I went to the store yesterday and the day after an +d the day after"; if ($String =~ m{(yesterday .+? after)}) { print $1; }
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: How do I extract the data that comes after a certain word?
by 2teez (Priest) on Jun 18, 2012 at 19:46 UTC

    Why use Perl $POSTMATCH or $'. when you can easily do like so:

    my $string='hello I went to the store yesterday and the day after an +d the day after'; if($string=~m/.+?(yesterday.+?after).+?$/i){ print 'Summary: ',$1,$/; ## print yesterday and the da +y after }

    Please check the following for some details.
    perldoc -v $`
    perldoc -v $&
    perldoc -v $'

      Whenever I try to modify this script to work for a much larger string, nothing happens. I think its because the words "Summary" and "Description" (Which is what I'm scraping between in my real script) keep on repeating. Is there a way to write it as a foreach loop to make it keep going through the script and writing everything it seems between the words "summary" and "description" every time its written??

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://976880]
Approved by tobyink
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2017-09-26 04:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    During the recent solar eclipse, I:









    Results (292 votes). Check out past polls.

    Notices?