正则表达式逻辑或

时间:2012-10-02 20:04:25

标签: c# regex

这是一个纯粹的学术练习,涉及正则表达式和我对多种模式分组的理解。我有以下示例字符串

<xContext id="ABC">
<xData id="DEF">
<xData id="GHI">
<ID>JKL</ID>
<str>MNO</str>
<str>PQR</str>
<str>
<order id="STU">
<str>VWX</str>
</order>
<order id="YZA">
<str>BCD</str>
</order>
</str>
</xContext>

使用C#Regex我试图提取3个大写字母的组。

目前,如果我使用模式>.+?</,我会得到

Found 5 matches:
>JKL</
>MNO</
>PQR</
>VWX</
>BCD</

如果我然后使用id=".+?">

Found 5 matches:
id="ABC">
id="DEF">
id="GHI">
id="STU">
id="YZA">

现在我正试图通过对双方的每个词使用逻辑OR |来组合它们id="|>.+?">|</

然而,这并没有给我两种模式的综合结果

我的问题是:

  1. 有人可以解释为什么这不能按预期工作吗?

  2. 如何更正模式,以便按照正确的顺序列出所有结果?

  3. 如何才能进一步增强组合模式,只提供字母?我希望它仍然是?<=?=<,但只是想检查一下。

  4. 谢谢

4 个答案:

答案 0 :(得分:4)

您的正则表达式不知道从哪里开始或停止由|分隔的替代选项。所以你需要将它们放在子模式中:

(id="|>).+?(">|</)

然而,regex is not the right tool to parse XML.

这些圆括号还添加捕获子图案。这可以由他们自己返回。所以这个:

(id="|>)(.+?)(">|</)

将返回索引0处的整个匹配,索引1处的前分隔符,索引2处的实际匹配以及索引3处的最后一个分隔符。在大多数正则表达式引擎中,您可以执行此操作:

(?:id="|>)(.+?)(?:">|</)

避免捕获分隔符。现在索引0将具有整个匹配,而索引1仅具有3个字母。不幸的是,我无法告诉你如何在C#中检索它们。

答案 1 :(得分:2)

您需要将备选方案组合在一起

(?:id="|>).+?(?:">|</)

要获得这些字母只能使用positve lookbehind and lookahead assertions

(?<=id="|>).+?(?=">|</)

here on Regexr

?<=?=开头的组是零宽度断言,这意味着它们不匹配(它们匹配的不是结果的一部分),它们只是“看”后面或进取。

答案 2 :(得分:1)

建议您使用正则表达式(?:(?<=id=")|(?<=>)).+?(?=">|</)

在RegExr上测试here

答案 3 :(得分:1)

捕获群组FTW!

@">(?<content>.+?)<|id=""(?<content>.+?)"""

具体来说,命名捕获组,因为.NET正则表达式使您可以在同一个正则表达式中使用相同的组名。在匹配对象上调用Groups["content"]将返回内容而不考虑其位置(即,在两个标记之间或id属性中)。