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?
编辑:您可能真的不想使用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修饰符。
也许不是您要找的答案,但是恕我直言,对于结构化数据,可以使用比正则表达式更简单的方法:
<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)