Areldy Exten
Areldy Exten

Reputation: 19

How to get this perl extended regex to work?

I have the following code


my @txt = ("Line 1. [foo]  bar",
           "Line 2.  foo   bar",
           "Line 3.  foo  [bar]"
          );
my $regex = qr/^
               Line     # Bare word
               (\d+)\.  # line number
               \[       # Open brace
               (\w+)    # Text in braces
               ]        # close brace
               .*       # slurp
               $
              /x;

my $nregex = qr/^\s*Line\s*(\d+)\.\s*\[\s*(\w+)\s*].*$/;

foreach (@txt) {
    if ($_ =~ $regex) {
        print "Lnum $1 => $2\n";
    }

    if ($_ =~ $nregex) {
        print "N Lnum $1 => $2\n";
    }
}

Output

N Lnum 1 => foo 

I am expecting both the regexs to be equivalent and capture only the first line of the array. However only $nregex works!

How can $regex be fixed so that it also works identically (with the x option)?


Edit

Based on the response, updated the regex and it works.

my $regex = qr/^       \s*
               Line    \s* # Bare word
               (\d+)\. \s* # line number
               \[      \s* # Open brace
               (\w+)   \s* # Text in braces
               ]       \s* # close brace
               .*          # slurp
               $
              /x;

Upvotes: 1

Views: 141

Answers (1)

user1646075
user1646075

Reputation:

Your two expressions are NOT the same. You need to have the \s* bits in the first one. The /x allows you to write neatly formatted expressions - with comments as you've noticed. As such, the spaces in the /x version are not considered significant, and will not contribute to any matching activity.

In other words, your /x version is the equivalent of

qr/^Line(\d+)\.\[(\w+)].*$/x

By the way, just having a plain space instead of \s* or \s+ would also fail many times; your sample data contains TWO spaces next to each other in a few places. These two places will not match a single space.

Final tip: when you MUST have at least one space in a certain position, you should use \s+ to enforce at least one space. You can surely figure out where that might be useful in your patterns once you know it is possible.

Upvotes: 4

Related Questions