2017-02-19 52 views
1

我想從長整型文本中重複字符串的長整型文本中檢索最短匹配項。但是,已經匹配的文本內的匹配未找到。最短正則表達式匹配(如果已經是另一個匹配項的一部分)

這裏是我現在面臨的問題的一個簡化版本:

  • 代碼:"ababc".match(/a.+c/g)
  • 把觀察結果:["ababc"]
  • 預期結果:["ababc", "abc"]

所以我想知道是否有比手動編寫遞歸代碼以在匹配內搜索更容易的方式來檢索子字符串​​。

+1

你會如何處理'ababcabc',做你想做的所有可能的排列或者是平時[重疊匹配處理(http://stackoverflow.com/questions/8235929/how-can-i -get-a-regex-to-find-every-match-in-javascript)夠了嗎? –

+0

我不認爲這個問題可以用正則表達式解決。正則表達式引擎僅在需要時纔會放棄匹配的字符,以滿足模式的其餘部分。 「這個匹配更短」不是那個標準的一部分 –

+0

@SebastianProske最終目標是找到最短匹配,因此它只需要在你的例子中找到'[「abc」,「abc」]' - 不需要所有的排列組合。如鏈接到的問題的答案之一所述,修改「lastIndex」屬性看起來相當不錯,所以感謝鏈接。 – greiner

回答

0

這是我因爲去了它的有效性,簡單和效率的答案:

let seq = "us warship"; 
let source = "The traditional US adversary has also positioned a spy ship off the coast of Delaware and carried out flights near a US Navy warship, concerning American officials."; 

let re = new RegExp(`\\b${seq.replace(/\s/g, "\\b.+?\\b")}\\b`, "gi"); 
let snippet = null; 
let matches; 
while (matches = re.exec(source)) { 
    let match = matches[0]; 
    if (!snippet || match.length < snippet.length) { 
    snippet = match; 
    } 
    re.lastIndex -= (match.length - 1); 
} 
console.log(snippet); // "US Navy warship" 

來源:https://stackoverflow.com/a/8236152/1055499

1

正如我的評論中所提到的,你無法單獨使用正則表達式來做你想要的。

你給出了一個簡化的例子,所以我不確定這會帶你走多遠,但是這裏是我在刺探你正在尋找的東西。我懷疑你的「a」和「c」字符是不一樣的,所以你需要相應地修改它(例如把它們作爲參數傳遞給函數)。

function getShortestMatch(str) { 
    var str = str || ''; 
    var match, 
    index, 
    regex, 
    length, 
    results = []; 
    // iterate along the string one character at a time 
    for (index = 0, length = str.length; index < length; index++) { 
    // if the current character is 'a' (the beginning part of our substring match) 
    if (str[index] === 'a') { 
     // create a new regex that first consumes everything up to 
     // the starting character. Then matches for everything from there to 
     // the ending substring char 'c'. It is a lazy match so it will stop 
     // at the first matched ending char 'c' 
     regex = new RegExp('^.{' + index + '}(a.+?c)'); 
     match = str.match(regex); 
     // if there is a match, then push to the results array 
     if (match && match[1]) { 
     results.push(match[1]); 
     } 
    } 
    } 
    // sort the results array ascending (shortest first) 
    results.sort(function(a,b){ 
    return a.length - b.length; 
    }); 

    // log all results matched to the console for sake of example 
    console.log(results); 

    // return the first (shortest) element 
    return results[0]; 
} 

getShortestMatch('ababcabbc'); 

// output showing all results found (from console.log in the function) 
["abc", "abbc", "ababc"] 

// return value 
"abc" 

注:此功能不會試圖找到所有可能的匹配,以 「一個 'A' 和 'C' 之間的一切」,因爲你的問題是:關於查找最短的之一。如果由於某種原因你想要所有可能的匹配,那麼一個貪婪的.+正則表達式會被扔進混合。

+0

顯然有點不相關,因爲你的輸出包含了'abc'的正確結果......但是隻是想知道爲什麼你認爲在你的例子中沒有匹配'ababcabbc'? –

+0

@RobinMackenzie是的,如果您要爲「ababcabbc」中的所有內容中的所有可能值列出「a」和「c」,則是,則完整字符串將位於列表中。我的筆記是要說明我的函數不匹配(因爲它只對每個索引處的最短值進行懶惰匹配) –

0

遍歷(使用slice),針對其被錨定到字符串(^)的開始的正則表達式匹配的從每個相繼的字符開始的子串,並使用非貪婪匹配(?):

const input = "ababc"; 
 
const regexp = /^a.+?c/; 
 

 
const results = []; 
 
    
 
for (var i = 0; i < input.length; i++) { 
 
    var match = input.slice(i).match(regexp); 
 
    if (match) results.push(match[0]); 
 
} 
 

 
console.log("all results are", results); 
 
var shortest = results.sort((a, b) => a.length - b.length)[0]; 
 
console.log("shortest result is", shortest);