Perl 带“的多个模式”|&引用;(“或”):确定所有匹配项?
我正在解析日志文件,希望一次根据多个模式匹配一行。我知道我可以从答复中的建议中获益。不幸的是,我不能使用它(因为它需要部署在几十台运行Perl的生产机器上,从5.8.8到5.18.0,以及AIX和SLES11/12) 所以我想我必须坚持使用Perl 带“的多个模式”|&引用;(“或”):确定所有匹配项?,perl,pattern-matching,Perl,Pattern Matching,我正在解析日志文件,希望一次根据多个模式匹配一行。我知道我可以从答复中的建议中获益。不幸的是,我不能使用它(因为它需要部署在几十台运行Perl的生产机器上,从5.8.8到5.18.0,以及AIX和SLES11/12) 所以我想我必须坚持使用|。我尝试了以下代码: #!/usr/bin/env perl use strict; use warnings; use Data::Printer; my @matches; @matches = ( 'sjd one skj two sjf' =~ /
|
。我尝试了以下代码:
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Printer;
my @matches;
@matches = ( 'sjd one skj two sjf' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
给予
给予
给予
给予
从这一点我可以判断是否有比赛@matches
表示不匹配或在相应位置包含匹配。
但在前两种情况下,实际上有两种匹配。在第一种情况下,是否有办法使代码输出同时匹配,如:
@matches = ( 'sjd one skj two sjf' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
即,@matches
包含所有匹配项,而不仅仅是第一个匹配项?
或者我必须使用if/else级联或其他方法循环我的模式吗
更新
重新阅读我的问题和你的评论,我意识到我的问题不清楚。很抱歉。事实上,我关心的是哪种模式匹配,以及匹配的结果,即线条
$line = 'xxx two xxx one xxx';
模式
/one/
,/t.o/
,/three/
我想知道模式/one/
匹配“one”
,模式/t.o/
匹配“two”
。这最多只需要一步。你在乎比赛的位置吗?如果不是,则应使用“非捕获括号”:(?:…)
与全局匹配标志组合使用/g
:
@matches = ( 'sjd one skj two sjf' =~ /(?:\bone\b)|(?:\btwo\b)|(?:\bthree\b)/g );
这将产生:
$VAR1 = [
'one',
'two'
];
你在乎比赛的位置吗?如果不是,则应使用“非捕获括号”:
(?:…)
与全局匹配标志组合使用/g
:
@matches = ( 'sjd one skj two sjf' =~ /(?:\bone\b)|(?:\btwo\b)|(?:\bthree\b)/g );
这将产生:
$VAR1 = [
'one',
'two'
];
以下内容查找所有匹配项,但输出不是您所要求的:
my @matches = /\b(one|two|three)\b/g;
以下内容正是您想要的:
my @matches;
($matches[0]) = /\b(one)\b/;
($matches[1]) = /\b(two)\b/;
($matches[2]) = /\b(three)\b/;
以下内容可在一个匹配中完成所有操作:
my @matches = /
^
(?= .* /\b(one)\b )
(?= .* /\b(two)\b )
.* /\b(three)\b
/xs;
以下内容查找所有匹配项,但输出不是您所要求的:
my @matches = /\b(one|two|three)\b/g;
以下内容正是您想要的:
my @matches;
($matches[0]) = /\b(one)\b/;
($matches[1]) = /\b(two)\b/;
($matches[2]) = /\b(three)\b/;
以下内容可在一个匹配中完成所有操作:
my @matches = /
^
(?= .* /\b(one)\b )
(?= .* /\b(two)\b )
.* /\b(three)\b
/xs;
使用Regexp::Assemble不需要5.10。事实上,Regexp::Assemble的主要用途和您感兴趣的用途(优化替代)在5.10中变得毫无用处(因为它是内置的)。@ikegami您指的是
~
操作符,对吗?不幸的是,我的脚本也必须在AIX下使用5.8.8运行,并且没有安装额外的组件:-(不,~
是实验性的,可能会改变。不应该使用它。//R::A基本上是my$re=join'|',@regex_patterns;
,但是以5.10+//中不需要的方式优化输出。这不是真的。你安装了一个脚本。因此你可以安装R::A。我还发现~
可疑,很高兴看到他r对于我来说,r::A似乎是多余的//技术上是正确的,但是一些“来自互联网的代码”必须得到It部门的人员的认可。这不是那么容易。使用Regexp::Assemble不需要5.10。事实上,Regexp::Assemble的主要用途和您感兴趣的用途(优化替代)在5.10中变得毫无用处(因为它是内置的)。@ikegami您指的是~
操作符,对吗?不幸的是,我的脚本也必须在AIX下使用5.8.8运行,并且没有安装任何附加程序:-(不,~
是实验性的,可能会改变。不应该使用它。//R::A基本上是my$re=join'|',@regex_patterns;
,但是以5.10+//中不需要的方式优化输出。这不是真的。你安装了一个脚本。因此你可以安装R::A。我还发现~
可疑,很高兴看到他r:r::A对我来说似乎是多余的//技术上是正确的,但有些“来自互联网的代码”必须得到ITSec部门人员的确认。这并不是那么容易。如果你不在乎是什么匹配触发了捕获,我建议这是最好的方法。例如,如果这个模式匹配,我想在日志文件中捕获一行。更新了我的答案。我想我必须修正我的问题:实际上我在乎是哪个匹配触发了捕获e捕获,因为该行需要进一步处理(取决于匹配的行)。如果您不关心是什么匹配触发了捕获,我建议这是最好的方法。例如,如果此模式匹配,我希望捕获日志文件中的一行。更新了我的答案。我想我必须修改我的问题:实际上我关心是哪个匹配触发了捕获,因为该行需要进一步处理(取决于哪一个匹配)。
my @matches = /\b(one|two|three)\b/g;
my @matches;
($matches[0]) = /\b(one)\b/;
($matches[1]) = /\b(two)\b/;
($matches[2]) = /\b(three)\b/;
my @matches = /
^
(?= .* /\b(one)\b )
(?= .* /\b(two)\b )
.* /\b(three)\b
/xs;