4

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

<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">

现在我试图通过|对两边的每个术语使用逻辑或来组合它们id="|>.+?">|</

但是,这并没有给我两种模式的组合结果

我的问题是:

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

  2. 如何更正模式以使两个结果以列出的正确顺序组合在一起

  3. 如何进一步增强组合模式以仅给出字母?我希望它仍然存在?<=?=<但只是想检查一下。

谢谢

4

4 回答 4

4

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

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

但是,正则表达式不是解析 XML 的正确工具。

这些圆括号还添加了捕获子模式。这个可以自己退。所以这:

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

将在索引 0 处返回整个匹配,在索引 1 处返回前分隔符,在索引 2 处返回您想要的实际匹配,在索引 3 处返回最后一个分隔符。在大多数正则表达式引擎中,您可以这样做:

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

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

于 2012-10-02T20:06:31.670 回答
2

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

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

并且为了得到这些字母,只使用正向的lookbehind和lookahead断言

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

在 Regexr 上查看

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

于 2012-10-02T20:11:37.790 回答
1

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

在RegExr上测试它。

于 2012-10-02T20:19:08.697 回答
1

捕获组 FTW!

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

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

于 2012-10-02T20:37:36.373 回答