【发布时间】:2016-04-23 17:09:23
【问题描述】:
我正在解析日志文件,并希望一次将一行与多个模式匹配。我知道我可以从Regexp::Assemble 中受益,正如this question 的答案中所建议的那样。不幸的是我不能使用它(因为它需要部署在数十台运行 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' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
给予
[ [0] "one", [1] undef, [2] undef ]
@matches = ( 'sjd onnne skj two sjf' =~ /(\bo.+e\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
给予
[ [0] "onnne", [1] undef, [2] undef ]
@matches = ( 'sjd ONE skj two sjf' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
给予
[ [0] undef, [1] "two", [2] undef ]
@matches = ( 'sjd ONE skj TWO sjf' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
给予
[]
由此我可以判断是否有匹配。 @matches 不匹配或包含对应位置的匹配是假的。
但在前两种情况下,实际上有 two 个匹配项。有没有办法让代码输出在第一种情况下都匹配,比如:
@matches = ( 'sjd one skj two sjf' =~ /(\bone\b)|(\btwo\b)|(\bthree\b)/ );
p @matches;
[ [0] "one", [1] "two", [2] undef ]
即这样@matches 包含 all 匹配项,而不仅仅是第一个匹配项?
或者我是否必须使用 if/else 级联或其他方式遍历我的模式?
更新
重新阅读我的问题和您的 cmets,我意识到我的问题并不清楚。很抱歉。
实际上我确实关心匹配的模式以及匹配的结果,即对于线
$line = 'xxx two xxx one xxx';
和模式/one/、/t.o/、/three/ 我想知道模式/one/ 匹配"one" 和模式/t.o/ 匹配"two"。最好是一步完成。
【问题讨论】:
-
您不需要 5.10 即可使用 Regexp::Assemble。事实上,Regexp::Assemble 的主要用途和您感兴趣的(优化交替)在 5.10 中变得无用(因为它成为内置的)。
-
@ikegami 您指的是
~~运算符,对吗?不幸的是,我的脚本还必须在安装了 no 附加功能的 AIX 下与 5.8.8 一起运行。 :-( -
不,
~~是实验性的,可能会改变。它不应该被使用。 // R::A 基本上是my $re = join '|', @regex_patterns;,但是以 5.10+ 中不需要的方式优化输出 // 这不是真的。您安装了一个脚本。因此,您可以安装 R::A。 -
我还发现
~~很可疑,很高兴听到 R::A 对我的情况来说似乎是多余的。 // 技术上是正确的,但是一些“来自互联网的代码”必须得到 ITSec 部门人员的确认。没那么容易。
标签: perl pattern-matching