2010-01-05 48 views
3

我把頭撞在牆上。我想要一個匹配的正則表達式:空字符串,A,ABABC,但不是AC。我有這個,它的工作原理:正則表達式匹配A,AB,ABC,但不匹配AC。 (「開頭」)

/^(A|AB|ABC)?$/ 

但這是一個簡化;在我的應用ABC實際上是長字符類,所以我不想一遍又一遍地重複它們。也許我只是沒有正確的看待它。我試過這個:

/^((AB?)C?)?$/ 

但是那仍然匹配AC

有沒有更簡單的方法來做到這一點,可以擴展到(說),ABCD,ABCDE等?

編輯:通過延伸到ABCDE,我的意思是會匹配:空字符串,AABABCABCDABCDE。基本上,一個「從」開始「的正則表達式。

+0

你想以什麼方式擴展它? – Gumbo 2010-01-05 16:09:16

+0

'C'不能以'A'開頭,否則'A'必須跟着'B'? – 2010-01-05 16:10:00

+0

所以你想允許'ABCD'而不是'ACD'和'ABCDE'而不是'ACDE'? – Gumbo 2010-01-05 16:11:35

回答

9

試試這個正則表達式:

^(A(B(C)?)?)?$ 

我想你可以看到這個模式並擴大它ABCDABCDE,如:

^(A(B(C(D)?)?)?)?$ 
^(A(B(C(D(E)?)?)?)?)?$ 

現在每個部分依賴於前述的部分(取決於A,C取決於B等)。

+0

如果C實際上不是單個字符,則可能會失敗。 – 2010-01-05 16:13:30

+0

@Carl Smotricz:謝謝,你說得對。 – Gumbo 2010-01-05 16:15:36

+1

謝謝。我不敢相信我沒有想到只是改變分組。這很容易擴展:'(A(B(C(D(E)?)?))?)?$'。這個網站也超快,發佈後我去搶咖啡,當我收到 – Jenni 2010-01-05 16:20:25

4

這應做到:

/^A(BC?)?$/ 
4
/^A(?:B(?:C)?)?$/ 

應該這樣做。

這是使用非捕獲組構造(?: xxx),以免混淆捕獲您可能正在做的任何匹配。

+0

謝謝時,已經有三個正確的答案。要匹配空字符串,你必須在另一個'(?:...)中匹配整個事物'' – Jenni 2010-01-05 16:28:31

+0

+1對於非捕獲分組 – rampion 2010-01-05 17:54:03

+0

@Jenni:是的,另一個嵌套層次應該這樣做。 – 2010-01-05 20:47:32

0

這似乎有點奢侈,但它適用於角色類以及角色。

(你會經常使用的indexOf如果它可以表示爲一個字符串。)

你曾經是能夠編輯正則表達式,但現在你需要一個新的有任何變化。

RegExp.prototype.extend= function(c){ 
var s= '', rx= this.toString(); 
rx= rx.replace(/(\W+)$/, c+'$1').replace(/^\/|\/$/g,''); 
if(this.global) s+= 'g'; 
if(this.multiline) s+= 'm'; 
if(this.ignoreCase) s+= 'i'; 
return RegExp(rx, s); 
} 

String.prototype.longMatch= function(arr){ 
// if(this=='') return true; 
var Rx= RegExp("^("+arr.shift()+")"); 
var i= 0, L= Math.min(s.length, arr.length), 
M= this.match(Rx); 
while(i< L){ 
    if(!M) return false; 
    Rx= Rx.extend(arr[i++]); 
    M= this.match(Rx); 
} 
return M[0]==this; 
} 

var arr= ['A','B','C','D']; 
var s= 'ABCD';// try various strings 
alert(s.longMatch(arr));