2015-08-14 52 views
1

我正在使用JavaScript從逗號分隔的成員字符串中提取「兄弟姐妹」的子集,我將其稱爲「生成」字符串。隱喻地說,成員都來自同一代,但他們並不都是兄弟姐妹(來自同一父母)。這裏有一個例子:JavaScript替代動態正則表達式中的所有量詞

// This is the generation string to search 
var generation = 'ABAA,ABAB,ABAC,ABAD,ABBA,ACAA,ACAB,ACAD,AEAB,AEAD,AFAA'; 

// This is the member for whom to extract siblings (member included) 
var member  = 'ACAA'; 

生成的字符串,其成員具有以下特點:

  • 每個成員都有相同的字符數爲他人
  • 字符串的所有成員都是字母排序
  • 每組兄弟姐妹將永遠彼此相鄰
  • 兄弟姐妹是那些成員誰共享完全相同的字母組合,除了拉斯噸信

繼續該示例...

// This is how I go about extracting the desired result: ACAA,ACAB,ACAD 
var mParent  = member.substr(0, member.length - 1) ; 
var mPattern = mParent + '[A-Z]'; 
var mPattern = '(.*)((' + mPattern + ')(,$1)*)(.*)'; // Trouble is here 
var mRegex  = new RegExp(mPattern); 
var mSiblings = generation.replace(mRegex, '$2'); 

在上面的構造圖案的關注正則表達式量詞確定的故障點。由於它的正上方,一切都是爲了貪婪,所以mSiblings的值是:

ACAD 

這只是最後一個成員。更改mPattern是在提取其他成員希望貪心不足得到解決以下

// Reluctant first expression yields ACAA 
var mPattern = '(.*?)((' + mPattern + ')(,$1)*)(.*)'; 

// Reluctant last expression yields ACAD,AEAB,AEAD,AFAA 
var mPattern = '(.*)((' + mPattern + ')(,$1)*)(.*?)'; 

// Reluctant first and last yields ACAA,ACAB,ACAD,AEAB,AEAD,AFAA 
var mPattern = '(.*?)((' + mPattern + ')(,$1)*)(.*?)'; 

如果我能把中間表達的佔有慾,這將是問題。像這樣:

// Make as many "middle" matches as possible by changing (,$1)* to (,$1)*+ 
var mPattern = '(.*?)((' + mPattern + ')(,$1)*+)(.*?)'; 

但正如我已閱讀(並有語法錯誤來證明它),JavaScript不支持所有格正則表達式量詞。有人可以提出解決方案嗎?謝謝。

回答

1

最明顯的問題是$1。在一個正則表達式中,你可以參考捕獲組#1使用\1,而不是$1。你的正則表達式中的(,$1)*永遠不會匹配任何東西。但是,小組參考無論如何不會有任何好處。

當您在正則表達式中使用組引用時,您沒有再應用那部分正則表達式,您只是匹配與第一次匹配的相同的東西。即,(ACA[A-Z])(,\1)*將匹配ACAA,ACAA,但不匹配ACAA,ACABACAA,ACAC。如果你想這樣做,你需要重複實際的正則表達式:(ACA[A-Z])(,ACA[A-Z])*。由於你動態生成正則表達式,這應該不成問題。

請注意,這是整個正則表達式:ACA[A-Z](,ACA[A-Z])*。沒有必要匹配您感興趣的部分之前或之後的內容;這隻會讓工作變得更加複雜(而且結果更令人困惑)。可以直接訪問匹配結果,而不是使用該「替換」噱頭:

var match = mRegex.exec(generation); 
if (match != null) { 
    mSiblings = match[0]; 
} 
+0

如果每個構件的長度不是固定的,則字邊界是必要的。如果它是固定的,那麼當前的解決方案是有效的。 – nhahtdh

+0

@nhahtdh:你說的是真的,但是OP確實說過所有成員的長度都是一樣的,除了最後一個字母之外,其他同胞都是一樣的。雖然代碼片段和聲明的輸出很混亂,但實際的*問題*(大約前三分之一)在這些點上是清楚的。 –