2012-11-06 70 views
2

我的問題相當簡單,即使其服務目的非常複雜。我將用一個簡單的例子:如何在配對內匹配配對

AzzAyyAxxxxByyBzzB 

所以通常我會想AB之間得到的一切。然而,因爲第一個A和最後B(一對)之間的一些內容包含額外的AB對,我需要推回比賽結束。 (不知道這最後一部分是否有意義)。

所以,我正在尋找的是一些正則表達式,讓我有以下的輸出:

Match 1 
    Group 1: AzzAyyAxxxxByyBzzB 
    Group 2: zzAyyAxxxxByyBzz 

然後,我會再次匹配它來獲得:

Match 2 
    Group 1: AyyAxxxxByyB 
    Group 2: yyAxxxxByy 

然後終於再次得到:

Match 3 
    Group 1: AxxxxB 
    Group 2: xxxx 

顯然,如果我嘗試(A(.*?)B)整體上輸入我得到:

Match x 
    Group 1: AzzAyyAxxxxB 
    Group 2: zzAyyAxxxx 

這是不是我要找的:)

我希望這是有道理的。我明白,如果這不能在RegEx中完成,但我想在我放棄它並嘗試其他方法之前,我會問你們中的一些正則表達式嚮導。謝謝!

附加信息:

我工作的項目是用Java編寫。其他

一個問題是,我解析其中可能包含這樣的一個文件:

AzzAyyAxxxxByyBzzB 
Here is some unrelated stuff 
AzzAyyAxxxxByyBzzB 
AzzzBxxArrrBAssssB 

和頂部AB對必須單獨從底部AB

回答

1

你讓你的正則表達式通過使用?明確無效。剛剛離開它和正則表達式會消耗盡可能匹配B前:

(A(.*)B) 

然而,在一般嵌套結構超出了正則表達式的範圍。在這樣的情況下:

AxxxByyyAzzzB 

你會現在也從第一A匹配到最後B。如果這種情況在您的情況下可能會發生,那麼您最好逐個字符地查看字符串,並計算A s和B s以確定哪些屬於一起。

編輯:

現在你已經更新了問題,我們在評論想通了這一點,你做多個連續配對的問題。在這種情況下,這不能用不支持遞歸的正則表達式引擎來完成。

但是,您可以切換到從內到外的匹配。

A([^AB]*)B 

這隻會得到最裏面對的,因爲有可能是既不A也不是分隔符之間的B。如果你找到它,你可以刪除這對,繼續你的下一場比賽。

+0

完美的解決方案,不幸的是我應該提到另一個約束。請參閱編輯。抱歉! – kentcdodds

+0

@kentcdodds其實我已經在編輯我的答案;)。那些「平行」的「A ... B」對總是隻出現在不同的線上?或者在一條線上可能會有多個連續的線對? –

+0

@kentcdodds您使用哪種語言或工具?一些正則表達式引擎支持簡單的遞歸,這可能會幫助你。 –

0

用字邊界,如果你使用多行模式:

\bA(.*)B\b #for matches that does not start from beginning of line to end 

^A(.*)B$ #for matches that start from beginning of line till end 
0

您將無法單獨使用正則表達式來做到這一點。你所描述的比Regular更多Context-Free。爲了解析這樣的事情,每次遇到「A」時需要將新上下文推送到堆棧,並且每次遇到「B」時都會彈出堆棧。您需要比正則表達式更類似pushdown automaton的內容。

+0

有幾個正則表達式可以解決給定的問題(例如PCRE)。通常,幾乎所有常見的正則表達式引擎都會通過允許反向引用和查找來推動「正則表達式」的含義。當然,從理論上講,我完全同意你的看法,儘管有幾個正則引擎可以處理這個問題,但它永遠不會是一個優雅的解決方案。但仍然,我認爲值得指出...... –

+0

@ m.buettner - 我很好奇:反向引用怎麼不正常?它們看起來像是關於匹配和捕獲組的實現細節,但我認爲它們並不影響語言的「規則性」。 –

+0

@ m.buettner - 抱歉;反向引用顯然是不規則的。我的意思是說「如何看待不常規」 –