Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 带“的多个模式”|&引用;(“或”):确定所有匹配项?_Perl_Pattern Matching - Fatal编程技术网

Perl 带“的多个模式”|&引用;(“或”):确定所有匹配项?

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' =~ /

我正在解析日志文件,希望一次根据多个模式匹配一行。我知道我可以从答复中的建议中获益。不幸的是,我不能使用它(因为它需要部署在几十台运行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;
给予

给予

给予

给予

从这一点我可以判断是否有比赛
@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;