Sumit
Sumit

Reputation: 2023

issue in matching regexp in perl

I am having following code

$str = "
   OTNPKT0553 04-02-03 21:43:46

M  X DENY

   PLNA

   /*Privilege, Login Not Active*/

;";

$val = $str =~ /[

]*([\n]?[\n]+
[\n]?)   ([^;^
]+)/s;

print "$1 and $2";

Getting output as

and PLNA

Why it is getting PLNA as output. I believe it should stop at first\n. I assume output should be OTNPKT0553 04-02-03 21:43:46

Upvotes: 0

Views: 41

Answers (3)

Borodin
Borodin

Reputation: 126742

You have a whole lot of newlines in there - some literal and some encoded as \n. I'm not clear how you were thinking. Did you think \n matched a number maybe? A \d matches a digit, and will also match many Unicode characters that are digits in other languages. However for simple ASCII text it works fine.

What you need is something like this

use strict;
use warnings;

my $str = "
   OTNPKT0553 04-02-03 21:43:46

M  X DENY

   PLNA

   /*Privilege, Login Not Active*/

;";

my $val = $str =~ / (\w+) \s+ ( [\d-]+ \s [\d:]+ ) /x;

print "$1 and $2";

output

OTNPKT0553 and 04-02-03 21:43:46

Upvotes: 2

Toto
Toto

Reputation: 91498

You have an extra line feed, change the regex to:

$str =~ /[

]*([\n]?[\n]+[\n]?)   ([^;^
]+)/s;

and simpler:

$str =~  /\n+   ([^;^\n]+)/s;

Upvotes: 1

Miller
Miller

Reputation: 35208

Your regex is messy and contains a lot of redundancy. The following steps demonstrate how it can be simplified and then it becomes more clear why it is matching PLNA.

1) Translating the literal new lines in your regex:

$val = $str =~ /[\n\n]*([\n]?[\n]+\n[\n]?)   ([^;^\n]+)/s;

2) Then simplifying this code to remove the redundancy:

$val = $str =~ /(\n{2})   ([^;^\n]+)/s;

So basically, the regex is looking for two new lines followed by 3 spaces.

There are three spaces before OTNPKT0553, but there is only a single new line, so it won't match.

The next three spaces are before PLNA which IS preceded by two new lines, and so matches.

Upvotes: 3

Related Questions