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

This is probably a stupid question with a simple elegant solution I haven't thought of.... How do I find the single line that matched in a multiline string without using .* and .* to capture everything either side of the actual regex?
$str = "this\nis my short\nstring\n"; $regex = "my"; if ($str =~ /(.*$regex.*/) { print "Matched Line $1\n" }

Replies are listed 'Best First'.
Re: Multiline Regex
by ikegami (Patriarch) on Oct 09, 2008 at 09:41 UTC

    I'm interested in knowing why you want this change.

    By the way, it should speed things up to to eliminate impossible starting points.

    if ( my ($line) = $str =~ /^(.*?$regex.*)/m ) { print "Matched Line $line\n" }

    The .*? on the LHS makes it behave more naturally if you add subcaptures.

      That's the best solution so far as it doesn't resort to splitting or file handles. Although, I was hoping there would be a way I could avoid the use of two .*'s.

        Although, I was hoping there would be a way I could avoid the use of two .*'s.

        Again, I wonder what you have against .*.

Re: Multiline Regex
by moritz (Cardinal) on Oct 09, 2008 at 09:37 UTC
    use 5.010; for (split m/\n/, $str) { say if m/$regex/; }

    If you don't want to capture the line, you have to extract the line first.

      Note: split /\n/ is only an acceptable of splitting text into lines if you don't care about eliminating trailing blank lines.

      $str = "this\nis my short\nstring\n\n"; $i=0; for (split /\n/, $str) { print(++$i, ": $_\n"); } print("\n"); $i=0; for ($str =~ /.*\n|.+/g) { # Just like <> print(++$i, ": $_"); }
        Note: split /\n/ is only an acceptable of splitting text into lines if you don't care about eliminating trailing blank lines.

        You can perhaps get around that by supplying a third argument to split of -1. The method does point up a non-existant empty line at the end of the file but that can be coped with by spliting to an array and poping if necessary.

        use strict; use warnings; my $str = qq{this\nis my short\nstring\n\n}; my $count = 0; for ( split m{\n}, $str, -1 ) { print ++ $count, qq{: $_\n}; }

        Produces

        1: this 2: is my short 3: string 4: 5:

        I hope this is of interest.

        Cheers,

        JohnGG

        If the regex can match the empty string, the OP has likely other problems than trailing empty lines. If it can't match the empty string, the example code will never fail.
Re: Multiline Regex
by jwkrahn (Abbot) on Oct 09, 2008 at 09:41 UTC
    my $str = "this\nis my short\nstring\n"; my $regex = 'my'; open my $FH, '<', \$str or die $!; while ( <$FH> ) { print "Matched Line $_" if /$regex/; }