perl正则表达式匹配,为什么找不到所有匹配项,为什么订单很重要?

时间:2017-11-08 16:48:01

标签: regex perl

我遇到了perl正则表达式匹配的问题。我把它降级到命令行上的一个小例子。为什么在这里尝试匹配的顺序很重要?

1

$ echo "XYG" | perl -ne 'if ($_ =~ m/X/gi) { print "Matches X\n"; } ; if ($_ =~ m/Y/gi) { print "Matches Y\n"; } ; if ($_ =~ m/G/gi) { print "Matches G\n"; } '
Matches X
Matches Y
Matches G

2

$ echo "GXY" | perl -ne 'if ($_ =~ m/X/gi) { print "Matches X\n"; } ; if ($_ =~ m/Y/gi) { print "Matches Y\n"; } ; if ($_ =~ m/G/gi) { print "Matches G\n"; } else { print "No match on G\n"; } '
Matches X
Matches Y
No match on G

1.示例按预期匹配所有三个字母,但第二个示例与字母G不匹配,为什么?

但是如果我创建一个中间变量,这里命名为$ aa:

$ echo "GXY" | perl -ne 'if ($_ =~ m/X/gi) { print "Matches X\n"; } ; if ($_ =~ m/Y/gi) { print "Matches Y\n"; } ; $aa = $_; if ($aa =~ m/G/gi) { print "Matches G\n"; } '
Matches X
Matches Y
Matches G

然后比赛再次起作用?

我的perl版本是:

$ perl -e 'print "$]\n";'
5.022001

在LM 18.2机器上

$ lsb_release -d

Description:    Linux Mint 18.2 Sonya

泰+ BR 最大

1 个答案:

答案 0 :(得分:5)

因为如果你在这样的标量上下文中匹配正则表达式,并设置g标志(用于全局匹配)它是迭代的 - 那就是允许你做while ( m/somepattern/g ) {这样的事情并拥有它触发多次。

那是因为g表示:

  

g - 在字符串

中重复全局匹配模式

如果每次尝试重置它都不是特别有用。但是你也可以在数组上下文中略微使用它:

my @matches = $str =~ m/(some_capture)/g; 

然后将它们全部选入列表中。

但是你的代码和正则表达式调试:

#!/usr/bin/env perl

use strict;
use warnings;

use re 'debug';

$_ = 'GXY';
if   ( $_ =~ m/X/gi ) { print "Matches X\n"; }
if   ( $_ =~ m/Y/gi ) { print "Matches Y\n"; }
if   ( $_ =~ m/G/gi ) { print "Matches G\n"; }
else                  { print "No match on G\n"; }

你会得到(为了简洁起见):

Matching REx "X" against "GXY" 
Matching REx "Y" against "Y"
Matching REx "G" against ""

第一场比赛'吃''GX'找到“X”,留下“Y”表示下一场比赛,但没有任何比赛用于“G”比赛。

简单的解决方法是省略g标记,因为那时你明确地说'匹配一次',你会得到:

Matches X
Matches Y
Matches G

或者,您可以将全局匹配与字符类一起使用:

$_ = 'GXY';

my @matches = m/([GYX])/g; #implicitly operates on $_
print "Match on $_\n" for @matches;