2010-10-09 35 views
5

查找JavaScript的最長重複子我想找到一個字符串中的最長重複串,用JavaScript實現,並使用正則表達式爲基礎的方法。使用正則表達式

我有一個PHP實現,當直接移植到JavaScript中,不能正常工作。

PHP實現從一個答案帶到問題"Find longest repeating strings?"

preg_match_all('/(?=((.+)(?:.*?\2)+))/s', $input, $matches, PREG_SET_ORDER); 

這將填充$matches[0][X](其中X$matches[0]的長度)與最長子串的重複在$input被發現。我用很多輸入字符串測試了這個,發現我確信輸出是正確的。

JavaScript中的最接近的直接端口是:

var matches = /(?=((.+)(?:.*?\2)+))/.exec(input); 

這不會給出正確的結果

 
input     Excepted result matches[0][X] 
====================================================== 
inputinput    input    input 
7inputinput   input    input 
inputinput7   input    input 
7inputinput7   input    7 
XXinputinputYY   input    XX 

我不熟悉不夠用正則表達式來理解這裏使用什麼正則表達式是在做。

當然,我可以實現的算法來查找最長的重複子字符串。在我嘗試這樣做之前,我希望不同的正則表達式能夠在JavaScript中產生正確的結果。

上述正則表達式是否可以修改,以便在JavaScript中返回預期的輸出?我承認,這可能不可能在一行中。

回答

5

JavaScript匹配只返回第一個匹配 - 你必須循環才能找到多個結果。一個小測試表明這得到預期的結果:

function maxRepeat(input) { 
var reg = /(?=((.+)(?:.*?\2)+))/g; 
var sub = ""; //somewhere to stick temp results 
var maxstr = ""; // our maximum length repeated string 
reg.lastIndex = 0; // because reg previously existed, we may need to reset this 
sub = reg.exec(input); // find the first repeated string 
while (!(sub == null)){ 
    if ((!(sub == null)) && (sub[2].length > maxstr.length)){ 
    maxstr = sub[2]; 
    } 
    sub = reg.exec(input); 
    reg.lastIndex++; // start searching from the next position 
} 
return maxstr; 
} 

// I'm logging to console for convenience 
console.log(maxRepeat("aabcd"));    //aa 
console.log(maxRepeat("inputinput"));  //input 
console.log(maxRepeat("7inputinput"));  //input 
console.log(maxRepeat("inputinput7"));  //input 
console.log(maxRepeat("7inputinput7"));  //input 
console.log(maxRepeat("xxabcdyy"));   //x 
console.log(maxRepeat("XXinputinputYY")); //input 

注意,對於「xxabcdyy」你只能得到「X」回來了,因爲它返回最大長度的第一個字符串。

0

看來JS正則表達式有點奇怪。我沒有一個完整的答案,但這是我發現的。

雖然我認爲他們做同樣的事情re.exec()和「串」 .match(RE)表現不同。 Exec似乎只返回它找到的第一個匹配,而匹配似乎返回所有的匹配(在兩種情況下都使用/ g)。

在另一方面,高管似乎與正常工作?=在正則表達式匹配,而所有返回空字符串。拆除?=給我們留下了

re = /((.+)(?:.*?\2)+)/g 

使用

"XXinputinputYY".match(re); 

回報

["XX", "inputinput", "YY"] 

re.exec("XXinputinputYY"); 

回報

["XX", "XX", "X"] 

所以至少在比賽你inputinput爲你的價值觀之一。顯然,這既不會拖出時間最長,也不會消除冗餘,但可能會有所幫助。其他

有一兩件事,我在大約扔不支持$ 1中的錯誤Firebug的控制檯進行測試,所以也許有什麼東西在$乏值得一看。