2010-08-20 119 views
3

我試圖設計一個正則表達式(在PHP),這將允許兩個子模式的任何交替。所以,如果一個模式匹配一​​組三個字母,而B組的2個數字相匹配,這些都將是美好的:正則表達式匹配模式交替的子模式

 
aaa 
aaa66bbb 
66 
67abc 
12abc34def56ghi78jkl 

我不介意它的子模式開始或結束的序列,只是後第一場比賽,子模式必須交替。我完全被這個難住了 - 任何建議都會被感激地收到!

+2

'abc12def34ghi'和'56jkl78mno'怎麼樣?他們應該匹配嗎? – 2010-08-21 02:59:59

+0

或'aaa11bbb22',對於這個問題? – cHao 2010-08-21 14:10:57

+0

是的,絕對。對不起,我不清楚。每次模式A或B匹配時,它們可能是不同的字符串 - 唯一重要的是它們必須交替。 所以'abc12def34ghi'或'aaa11bbb22'都是有效的匹配。 – 2010-08-22 10:41:42

回答

2

這裏有一個通用的解決方案:

^(?:[a-z]{3}(?![a-z]{3})|[0-9]{2}(?![0-9]{2}))+$ 

這是一個簡單的交替 - 三個字母或兩個數字 - 但負向預測確保相同的替代方案不會連續兩次匹配。這裏只是對PHP稍微更優雅的解決方案:

/^(?:([a-z]{3})(?!(?1))|([0-9]{2})(?!(?2)))+$/ 

取而代之的是相同的子模式多次輸入,你可以把它們捕捉組,並使用(?1)(?2)等其它什麼want--再次應用它們在這種情況下,在向前看。

+0

我也喜歡這個選項 - 類似於cHao的答案,但也許更時尚一些? 謝謝Alan。 – 2010-08-23 10:18:42

2
"/^(?:$A(?:$B$A)*$B?|$B(?:$A$B)*$A?)\$/" 

將匹配模式A,接着然而,許多交替模式B的與模式的,也許一個最終的B ...或B,接着然而,許多A-B對加上一個A,如果它的存在。

,因爲你要去有一些插值做我做了這樣的字符串(和逃脫最終$)。確保$ A和$ B處於某種分組狀態(如圓括號),如果您希望匹配正確的話。在實施例中,$ A可能是 '([A-ZA-Z] {3})' 和$ B可能是 '(\ d \ d)'。

注意,如果你想匹配的相同字母或數字,或實例組的字母或數字相同的一些數字,你需要做一些魔術反向引用 - 可能命名者,因爲任何編號後向引用將取決於捕獲組的數量你想要的之前(或你想要的和你在哪裏之間),但這個數字變得複雜,如果子模式中都有括號。

+0

([a-zA-Z] {3})這將匹配'aXu'。並且(\ d \ d)將匹配'10' – jigfox 2010-08-21 00:54:38

+0

@jigfox:模式匹配「一組三個字母」和「一組兩個數字」,這正是OP所說的。 – cHao 2010-08-21 00:55:33

+0

是的,但是這個例子提出了一個更具體的組 – jigfox 2010-08-21 01:03:11

0
/\b(?:(([a-z])\2\2)(?:(([0-9])\4)\1)*(?:([0-9])\5)?|(([0-9])\7)(?:(([a-z])\9\9)\6)*(?:([a-z])\10\10)?)\b/ 

,或者如果你想允許三人小組中的任何非數字字符:

/\b(?:((\D)\2\2)(?:((\d)\4)\1)*(?:(\d)\5)?|((\d)\7)(?:((\D)\9\9)\6)*(?:(\D)\10\10)?)\b/ 

這將匹配由兩個交替組一個組由相同的字符3倍的任何模式另一個是同一位數的2倍。

這正則表達式匹配

 
aaa 
11 
bbb22 
33ccc 
ddd44ddd 
55eee55 
fff66fff66 
77ggg77ggg 

但不是

 
aaa11bbb 
+0

這不允許「任何兩個子模式的交替」。它只會匹配示例子模式,當時所要求的是更通用的解決方案。 – cHao 2010-08-21 01:05:20

+0

我想說這是解釋的問題! – jigfox 2010-08-21 01:07:08

+0

哦,所以現在它是「解釋的問題」!雖然你低估了我,但它並不是那麼主觀... ... – cHao 2010-08-21 01:11:22