in reply to parsing data pairs from single line

A couple techniques would likely be helpful for you. If you change your whitespace \s to a word boundary \b, it will match at the end of a line. As well, using look ahead assertions, you can stop when you next hit one of your delimiters.

#!/usr/bin/perl use strict; use warnings; my $data = 'pro my project con my customer date 2009-10-5 at 17:00 pri + 2 msg Rack new server'; #pro = my project #con = my customer #date = 2009-10-5 #at = 17:00 #pri = 2 #msg = Rack new server my @keywords = qw(pro con due date at pri msg); # \b(pro|con|due|date|at|pri|msg)\s((?:(?!(pro|con|due|date|at|pri|msg +)\b).)*) my $regex = '\b(' . join('|', @keywords) . ')\s((?:(?!(' . join('|', @ +keywords) . ')\b).)*)'; while ($data =~ /$regex/ig) { print "$1 = $2\n"; }

See perlretut for more info.

Replies are listed 'Best First'.
Re^2: parsing data pairs from single line
by johngg (Canon) on Oct 14, 2009 at 20:58 UTC
    my $regex = '\b(' . join('|', @keywords) . ')\s((?:(?!(' . join('|', @keywords) . ')\b).)*)';

    Rather than all the concatenation and the joins, you could take advantage of the double-quote-like behaviour of regexen by localising the list separator in a do block and interpolating @keywords.

    my $regex = do { local $" = q{|}; qr{(?x) \b (@keywords) \s ( (?: (?! (@keywords) \b ) . )* ) } };

    It looks a little clearer to my eye.

    Cheers,

    JohnGG