Perl regex one line file

Mar*_*n K 2 regex perl file

I'm using cat to get content of the file, and then I use regex to get what I want. When I change order of if's in example i put PASSWORD as a second one, IP will be empty.

#!/usr/bin/perl
my $param = $ARGV[0];

my $IP;
my $PASSWORD;
my $MODEM;
my @cat = `cat file`;

 foreach my $line (@cat){
    if ($line =~ /$param/){
        if ($line =~ /MODEM:(\w+)/g){ $MODEM = $1; }
        if ($line =~ /IP:((\d{1,3}\.){3}\d{1,3})/g){ $IP = $1; }
        if ($line =~ /PASSWORD:(.+)/g){ $PASSWORD = $1; }

        print $MODEM;
        print $IP;
        print $PASSWORD;

        }
}
Run Code Online (Sandbox Code Playgroud)

The content of a file (data is changed to fake values) :

MODEM:SOMETHING ID:1000018 MAC:606060606060  ID2:123499  IP:1.1.1.1  PASSWORD:pass123
Run Code Online (Sandbox Code Playgroud)

Expected result is:

SOMETHING1.1.1.1pass123 
Run Code Online (Sandbox Code Playgroud)

But when I change the line of code to this:

if ($line =~ /MODEM:(\w+)/g){ $MODEM = $1; }
if ($line =~ /PASSWORD:(.+)/g){ $PASSWORD = $1; }
if ($line =~ /IP:((\d{1,3}\.){3}\d{1,3})/g){ $IP = $1; }
Run Code Online (Sandbox Code Playgroud)

the result is :

SOMETHINGpass123 
Run Code Online (Sandbox Code Playgroud)

i.e. the IP is empty. Can someone explain me why this is happening?

Dad*_*ada 7

编辑:您可能真的不想使用3个复杂的正则表达式来解析您的文件。请参阅Stefan Becker的答案,以获得更好的方法。

您需要删除/g修饰符。

/g从上一个匹配项的末尾开始,对同一字符串进行连续匹配。看看perlretut中的相关段落。
在文件中,MODEM先出现IP,然后是PASSWORD。这意味着匹配后/PASSWORD:(.+)/g,您将无法匹配/IP/g字符串中的前一个。


/g 修饰符在您想要执行类似操作时最有用

while ($string =~ /.../g) { ... }
Run Code Online (Sandbox Code Playgroud)

或者,当然,在列表上下文中,获取所有匹配项:

 @matches = $string =~ /.../g
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您只想一一获得不同的匹配项,因此不需要/g修饰符。


Ste*_*ker 7

也许不是您要找的答案,但是恕我直言,对于结构化数据,可以使用比正则表达式更简单的方法:

  • 在空白处分割以访问字段
  • 每个字段都是形式<KEY>:<VALUE,即可以转换为哈希
#!/usr/bin/perl
use warnings;
use strict;

while (<DATA>) {
    chomp;
    my %fields = map { split(/:/) } split(' ');

    print "$fields{MODEM} $fields{IP} $fields{PASSWORD}\n"
}

exit 0;

__DATA__
MODEM:SOMETHING ID:1000018 MAC:606060606060  ID2:123499  IP:1.1.1.1  PASSWORD:pass123
Run Code Online (Sandbox Code Playgroud)

另一种选择是

my %fields = /(\S+):(\S+)/g;
Run Code Online (Sandbox Code Playgroud)

测试运行:

$ perl dummy.pl
SOMETHING 1.1.1.1 pass123
Run Code Online (Sandbox Code Playgroud)