2013-10-08 36 views
2

這是爲什麼發生?我有一個複雜的正則表達式,但這是讓我瘋狂的原因。a {0,1} | b {0,1}只匹配'a',爲什麼?

a|b 

匹配任一單個a或單b

a+|b+ 

匹配任何系列的a或一系列b

a{1}|b{1} 

匹配兩個單個字母相同。

但我需要這樣做:

a{0,2}|b{0,2} 

而這正則表達式只匹配a並沒有b可言。那有什麼問題?

更有趣的是,如果我將0更改爲1,以便它的{1,2}開始正確匹配(或更好,如預期的那樣)。

因爲它似乎現在很清楚,我加入我的真實的例子:

my $launch_regexp = '(\d*)d{0,1}(\d*)(\+{0,2}|-{0,2})(\d*)'; 
($dice, $fc, $op, $mod) = ($launch =~ /$launch_regexp/); 

哪裏$launch是一樣的$ARGV[1]

我想匹配很多東西。例子:

3 (numbers) 

d10 (d + numbers) 

3d10 (numbers + d + numbers) 

3d10+/-5 (numbers + d + numbers + (+|-) + numbers) 

3d10++/--5 (numbers + d + numbers + (++|--) + numbers) 

我知道我的正則表達式也匹配其他字符串,但現在它與+而不是與-工作。

如果我改變範圍{1,2},它匹配字符串與+和 - (但我需要匹配也沒有這種修飾符的字符串)。

這是發生在我的機器上與Perl 5.16.3,我可以在this website重現它。

+4

'A {0,2}'是'包含任何B'串一個完全有效的匹配,因爲它匹配'B'零次。你想通過提供投入和預期產出來澄清你的問題嗎? – TLP

+0

{0,2}與0 a的匹配值最高爲1.因此,您可能不會擁有該案例,因爲它永遠無法達到該案例。您需要確定它至少匹配1個a或至少1個b。 – scrappedcola

+0

您正在使用哪種正則表達式引擎?我無法使用PCRE兼容引擎重現您的問題,或者我誤解了它。 –

回答

7

字符串「b」可以與正則表達式a{0,2}匹配,因爲它正確地具有零個「a」實例。它不會捕獲,但它會匹配。

爲了配合',「AA」或「BB」,你想(aa|bb)?和包裝你的整個正則表達式中^$

我想你想要什麼,你的解決方案是:(\d*)d?(\d+)(?:(\+{1,2}|\-{1,2})(\d*))?

+0

哦,是的。我沒有想過它會匹配的事實。但是,如果我想匹配'a'或'aa'或'b'或'bb',並且如果找不到它們,將我的變量分配給空字符串?這是可能的正則表達式? – Zagorax

+0

我已更新以匹配新信息。它會匹配一些時髦的其他東西,但如果你的輸入是有效的,它會適當地分割它。 – stevemarvell

+1

@stevemarvell:這很容易實現:'split /(\ d +)/'會做到這一點。 – Borodin

2

Perl更喜歡字符串中最早匹配的任何內容。接下來,它傾向於選擇最早的一系列|(不是最長的,就像一些正則表達式引擎一樣)。 因爲你的第一個替代方法什麼都不能匹配,perl會在字符串的開始處這樣做,對於任何不以a開頭的字符串。

你可能想是這樣的:

my ($find) = ($string) =~ /^[^ab]*(a{1,2}|b{1,2}|\z)/; 
+0

除非它有以下文字 – stevemarvell

+0

@stevemarvell:除非有以下文字,否則會發生什麼? – ysth

+0

我的意思是說如果在這場比賽之後有下面的文字,那麼'\ z'不合適。 – stevemarvell

相關問題