初學者的問題。在代碼:在Perl中重疊模式匹配
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+)(g.+)/);
print "$b[0]\n";
爲什麼$b[0]
等於aaagg
,而不是aaa
?換句話說 - 爲什麼第二組 - (g.+)
- 僅匹配從最後的g
?
初學者的問題。在代碼:在Perl中重疊模式匹配
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+)(g.+)/);
print "$b[0]\n";
爲什麼$b[0]
等於aaagg
,而不是aaa
?換句話說 - 爲什麼第二組 - (g.+)
- 僅匹配從最後的g
?
因爲第一個.+
是「貪婪」,這意味着它會嘗試匹配儘可能多的字符。
如果你想表明這種「貪婪」的行爲,你可以用.+?
代替.+
,所以/(a.+?)(g.+)/
將返回('aaa','gggaaa')。
也許,你想寫/(a+)(g+)/
(只有'在第一組和第二個'G')。
Perl正則表達式通常匹配可能的最長字符串。
在您的代碼中,它與最後的g
匹配並返回輸出aaagg。如果你想得到輸出爲aaa,那麼你需要使用非貪婪的行爲。使用此代碼:
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+?)(g.+)/);
print "$b[0]\n";
這將輸出:
aaa
顯然,使用question mark
使得比賽ungreedy。
正則表達式,你寫道:
($a =~ /(a.+)(g.+)/);
抓了"a"
任何字,因爲它可以在一個"g"
其次是更多的字符整理。因此,第一個(a.+)
只是匹配"aaagg"
直到正則表達式的第二部分的匹配:(g.+)
=>"gaaa"
的@b
陣列接收兩個比賽"aaagg"
和"gaaa"
。所以,$b[0]
只是打印"aaagg"
。
通常一個正則表達式是貪婪的。您可以使用?
字符將其關閉:
$a = 'aaagggaaa';
my @b = ($a =~ /(a.+)(g.+)/);
my @c = ($a =~ /(a.+?)(g.+)/);
print "@b\n";
print "@c\n";
輸出:
aaagg gaaa
aaa gggaaa
但我不知道這是你想要的!那麼abagggbb
?您需要aba
?
問題是,第一個.+
導致g
儘可能地匹配。
爲了向您展示真正發生的事情,我修改了您的代碼以輸出更多說明debug信息。
$ perl -Mre=debug -e'q[aaagggaaa] =~ /a.+[g ]/'
Compiling REx "a.+[g ]"
Final program:
1: EXACT <a> (3)
3: PLUS (5)
4: REG_ANY (0)
5: ANYOF[ g][] (16)
16: END (0)
anchored "a" at 0 (checking anchored) minlen 3
Guessing start of match in sv for REx "a.+[g ]" against "aaagggaaa"
Found anchored substr "a" at offset 0...
Guessed: match at offset 0
Matching REx "a.+[g ]" against "aaagggaaa"
0 <> <aaagggaaa> | 1:EXACT <a>(3)
1 <a> <aagggaaa> | 3:PLUS(5)
REG_ANY can match 8 times out of 2147483647...
9 <aaagggaaa> <> | 5: ANYOF[ g][](16)
failed...
8 <aaagggaa> <a> | 5: ANYOF[ g][](16)
failed...
7 <aaaggga> <aa> | 5: ANYOF[ g][](16)
failed...
6 <aaaggg> <aaa> | 5: ANYOF[ g][](16)
failed...
5 <aaagg> <gaaa> | 5: ANYOF[ g][](16)
6 <aaaggg> <aaa> | 16: END(0)
Match successful!
Freeing REx: "a.+[g ]"
注意,第一個.+
被捕捉一切可能與開始了。
然後它必須回溯到g
可以匹配。
你可能想要的是一個:
/(a+ )(g+ )/x;
/(a.+? )(g.+)/x;
/(a+ )(g.+)/x;
/(a[^g]+)(g.+)/x;
/(a[^g]+)(g+ )/x;
# etc.
沒有更多的信息來自你,那是不可能知道你想要的是什麼正則表達式。
真正的正則表達式本身就是一種語言,它比其他Perl更復雜。
如果您想查看Perl正則表達式引擎,請嘗試[Regexp :: Debugger](https://metacpan.org/pod/Regexp::Debugger)模塊中的'rxrx'實用程序。這是非常酷和教育。 – jreisinger