http://qs1969.pair.com?node_id=324315

Hoot has asked for the wisdom of the Perl Monks concerning the following question:

Hi Say I have a poem called:

A Beautiful Poem
Mary had a little lamb, little lamb, little lamb
Mary had a DOG but everywhere that mary went the lamb was
sure to go even though it did not like the dog very much.

Is it possible to have DOG as the pattern to match and store everything before it in a variable and everything after it in another variable?

I have tried $` and $& and $' but can't get my head around the new lines etc.

I want to be able to capture the title of the poem and the poem itself and DOG.

Can somebody help me please?

Replies are listed 'Best First'.
Re: Storing Lines before and After pattern
by Zaxo (Archbishop) on Jan 27, 2004 at 01:05 UTC

    This will break on every occurance of DOG, my @parts = split /DOG/, $poem;

    This will break on the first occurance, my ($before, $after) = split /DOG/, $poem, 2; You can also do things with regexes or substr, rindex, and index

    After Compline,
    Zaxo

Re: Storing Lines before and After pattern
by allolex (Curate) on Jan 27, 2004 at 00:58 UTC

    This sooo looks like homework. Oh, well.

    You'll probably be interested in the s modifier for regex matching. (See perlre for more detail.):

    #!/usr/bin/perl use strict; use warnings; my $poem; { local $/ = undef; $poem = <DATA>; } my( $before, $after) = $poem =~ m/(.*)\bDOG\b(.*)/s; print "Text before:\n$before\n\n"; print "Text after:\n$after\n\n"; __DATA__ A Beautiful Poem Mary had a little lamb, little lamb, little lamb Mary had a DOG but everywhere that mary went the lamb was sure to go even though it did not like the dog very much. # Output Text before: A Beautiful Poem Mary had a little lamb, little lamb, little lamb Mary had a Text after: but everywhere that mary went the lamb was sure to go even though it did not like the dog very much.

    --
    Allolex

      If you enjoy saving a few keystrokes here and there (and who doesn't?), you can replace

      my $poem; { local $/ = undef; $poem = <DATA>; }

      with this:

      my $poem = do { local $/; <DATA> };

      IMHO, it's not only shorter, it's also more readable, since you are assigning the entore operation to the variable. ;)

Re: Storing Lines before and After pattern
by jweed (Chaplain) on Jan 27, 2004 at 01:00 UTC
    Because of $` and $' overhead, this is an ideal place for split:
    open ($fh, "<poem") or die "Couldn't Open!"; $poem = do{ local $/; <$fh> }; ($before, $match, $after} = split /(DOG)/, $poem;



    Code is (almost) always untested.
    http://www.justicepoetic.net/
      If there may be multiple occurrences of DOG, you want:
      ($before, $match, $after) = split /(DOG)/, $poem, 2;
      or $after will only include up to the second DOG.
Re: Storing Lines before and After pattern
by Abigail-II (Bishop) on Jan 27, 2004 at 01:00 UTC
    What do you mean with "I can't get my head around the new lines"? $` and friends don't need anything special for newlines.
    my $poem = "...."; if ($poem =~ /DOG/) { print "Before DOG: $`"; print "After DOG: $'"; }

    Abigail