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

Hi all!

I am dealing with a string that can appear several different ways. I am basically looking for a string that either contains, one line of location coordinates, several lines of location coordinates, or no lines of location coordinates. An example of a location coordinate is this: "25NE 0SE 0SW 25NW". The area that I need to search in will occur after the words "MAX SUSTAINED WINDS" and before the word "REPEAT". Here are some examples of what I am talking about:

Here is the possibility with no location coordinates:

MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT.
REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z

Here is the possibility with one location coordinate:

MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT.
64 KT....... 25NE 0SE 0SW 25NW.
REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z

Here is the possibility with more than one location coordinate:

MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT.
64 KT....... 25NE 0SE 0SW 25NW.
50 KT....... 40NE 0SE 0SW 40NW.
34 KT.......100NE 75SE 0SW 75NW.
12 FT SEAS..175NE 100SE 50SW 175NW.
REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z

I know how to figure out if there are no location coordinates, or one location coordinate, but if there are more than one location coordinates, how can I capture each one into a string value. So, in the example above I would want something like this:

$string1 = "25NE 0SE 0SW 25NW"
$string2 = "40NE 0SE 0SW 40NW"
$string3 = "100NE 75SE 0SW 75NW"
$string4 = "175NE 100SE 50SW 175NW"

I am trying to do this just with regex. I prefer not to start splitting the string into array values and working on it that way. Many thanks for any advise!!

Replies are listed 'Best First'.
Re: Need soom regex expertise
by BrowserUk (Patriarch) on Jan 08, 2005 at 00:05 UTC

    Take two bites at the cherry. First extract the (possibly null) string between the first and last record and then extract the coordinates from that:

    #! perl -slw use strict; local $/ = ''; ## paragraph mode while( <DATA> ) { print "\n'$_' contains"; if( my( $coords ) = m[MAX.*?\n(.*)\nREPEAT]s ) { my @coords = $coords =~ m[((?:\d+(?:NW|N|NE|E|SE|S|SW|W)[ .]+) +{4})]g; print "\t$_" for @coords; } else { print 'No coords'; } } __DATA__ MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. 50 KT....... 40NE 0SE 0SW 40NW. 34 KT.......100NE 75SE 0SW 75NW. 12 FT SEAS..175NE 100SE 50SW 175NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z

    Produces:

    P:\test>420431 'MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z ' contains No coords 'MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z ' contains 25NE 0SE 0SW 25NW. 'MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. 50 KT....... 40NE 0SE 0SW 40NW. 34 KT.......100NE 75SE 0SW 75NW. 12 FT SEAS..175NE 100SE 50SW 175NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z ' contains 25NE 0SE 0SW 25NW. 40NE 0SE 0SW 40NW. 100NE 75SE 0SW 75NW. 175NE 100SE 50SW 175NW.

    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.
Re: Need soom regex expertise
by gopalr (Priest) on Jan 08, 2005 at 10:56 UTC

    Hi,

    $INPUT=' MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. 50 KT....... 40NE 0SE 0SW 40NW 40NE 0SE 0SW 40NW. 34 KT.......100NE 75SE 0SW 75NW. 12 FT SEAS..175NE 100SE 50SW 175NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z '; $cnt=1; $INPUT=~s#MAX SUSTAINED WINDS(.+?)REPEAT#Match($1)#egs; sub Match { my ($line)=@_; while ($line=~m#[0-9]+NE [0-9]+SE [0-9]+SW [0-9]+NW#g) { push (@OUT, $&); } return $line; } $"="\n"; print "@OUT";

    Thanks,

    Gopal.R

Re: Need soom regex expertise
by perlsen (Chaplain) on Jan 08, 2005 at 09:10 UTC

    if u wish u can try this following

    $str='MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. 64 KT....... 25NE 0SE 0SW 25NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0S 0SW 25NW. 50 KT....... 40NE 0SE 0SW 40W. 34 KT.......100NE 75SE 0SW 75NW. 12 FT SEAS..175NE 100SE 50SW 175NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z'; my @text=split(/\n/,$str); my @find=(); for (@text) { if ($_ =~ m#((\d+[SNEW]{1,2} ){3}\d+[SNEW]{1,2})#gsi) { push(@find,$1); } } print "$_\n" for @find ;

    output:

    *************

    25NE 0SE 0SW 25NW

    25NE 0SE 0SW 25NW

    25NE 0S 0SW 25NW

    40NE 0SE 0SW 40W

    100NE 75SE 0SW 75NW

    175NE 100SE 50SW 175NW

    Regards,

    senthil kumar.k

Re: Need soom regex expertise
by holli (Abbot) on Jan 08, 2005 at 06:28 UTC
    #! perl -slw use strict; local $/ = ''; ## paragraph mode while (<DATA>) { my $k = '\d{1,3}[SNEW]{1,2}'; while ( /\G.*?(($k ){3}$k)/msg ) { print "*$1*"; } } __DATA__ MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0SE 0SW 25NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z MAX SUSTAINED WINDS 65 KT WITH GUSTS TO 80 KT. 64 KT....... 25NE 0S 0SW 25NW. 50 KT....... 40NE 0SE 0SW 40W. 34 KT.......100NE 75SE 0SW 75NW. 12 FT SEAS..175NE 100SE 50SW 175NW. REPEAT...CENTER LOCATED NEAR 17.0N 77.5W AT 11/2100Z __END__
    OUTPUT:
    *25NE 0SE 0SW 25NW*
    *25NE 0S 0SW 25NW*
    *40NE 0SE 0SW 40W*
    *100NE 75SE 0SW 75NW*
    *175NE 100SE 50SW 175NW*