2016-12-27 70 views
1

爲什麼下面的正則表達式返回101而不是1001+應該是貪婪的,爲什麼我會得到一個懶惰的結果?

console.log(new RegExp(/1(0+)1/).exec('101001')[0]);

我認爲+是貪婪的,所以這兩個比賽的時間越長應返回。

IMO與Using javascript regexp to find the first AND longest match不同,因爲我不關心第一個,也就是最長的。有人能糾正我對貪婪的定義嗎?例如,上面的代碼片段與new RegExp(/<(.+)>/).exec('<b>a</b>')[0]給出的b>a</b的經典「oops,too greedy」示例有什麼區別?

(注:這似乎是語言無關(這也發生在Perl),但只是爲了便於在瀏覽器中運行它,我這裏使用的JavaScript。)

+0

正則表達式是不提取最長匹配正確的工具。你可能會得到所有的子串,用'^ 10 + 1 $'模式進行測試,並使用特定於語言的方法得到最長的子串。 –

+0

在匹配函數中使用'/ 1(0+)1 /'正則表達式,並通過對結果應用長度函數來找到最長匹配。 –

+1

'+'是貪婪的,但它會首先比賽,中間的'1'被包含在第一場比賽中,所以它不會被包含在將來的比賽中,並且'1001'不會被匹配。 – muru

回答

1

貪婪手段到最右邊出現,它從不意味着在輸入字符串最長的

正則表達式本身並不是提取最長匹配的正確工具。你可能會得到符合你的模式的所有子字符串,並使用特定於語言的方法得到最長的一個。

由於從左至右的字符串進行分析,101101001首先得到匹配,其餘(001)將不匹配(如1011001比賽是重疊)。您可以使用/(?=(10+1))./g,然後檢查每個組1的長度以獲得最長的值。

var regex = /(?=(10+1))./g; 
 
var str = "101001"; 
 
var m, res=[]; 
 

 
while ((m = regex.exec(str)) !== null) { 
 
    res.push(m[1]); 
 
} 
 
console.log(res); // => ["101", "1001"] 
 

 
if (res.length>0) { 
 
    console.log("The longest match:", res.sort(function (a, b) { return b.length - a.length; })[0]); 
 
} // => 1001

3

正則表達式總是讀從左對!它不會再尋找更長的東西。在多個匹配的情況下,你必須重新執行正則表達式來獲取它們,並且自己比較它們的長度。

+0

那麼你能提供一個更好的'貪心'的定義嗎? (這是不是表示,找到最長的?) – Kev

+0

貪婪意味着它儘可能匹配。例如:你的字符串「101001」。如果你使用這個正則表達式「1. + 1」,它會匹配所有的,因爲它是貪婪的。但是如果你使用這個正則表達式'1。+?1',它不會貪婪,只會匹配「101」(請參閱​​https://regex101.com/r/GeDOZL/1)。我希望我的解釋是明確的 – Fallenhero

+0

對,那麼儘可能多的不是'1(0+)1'的字符串是不是'1001',而不是'101'? – Kev

相關問題