2012-11-06 47 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 - 抱歉;反向引用显然是不规则的。我的意思是说“如何看待不常规” –