正则表达式 包含在 XML 元素中

Posted

技术标签:

【中文标题】正则表达式 包含在 XML 元素中【英文标题】:Regex Contains in the XML element 【发布时间】:2017-11-07 07:53:03 【问题描述】:

如何在正则表达式中使用“contains”(“Contains”或“%like%”)?

我有一个正则表达式来匹配 XML 节点和确切的文本:

<([\w]+)[^>]*>sample<\/\1>

它会产生准确的节点名称,但我想像在 C# 和 SQL (%LIKE%) 中一样应用正则表达式。

文字:

    <Part>this is sample part</Part>
    <Remarks>this is sample remark</Remarks>
    <Notes>this is sample notes</Notes>
    <Desc>sample</Desc>

预期的正则表达式结果应该返回以上所有节点,但目前它只返回最后一个节点。

我创建了a sample here to test。

【问题讨论】:

作业工具错误。正则表达式不是 XML 解析器,也不可能 为什么不使用 XPath? //*[contains(text(), "sample")]/local-name() @WiktorStribiżew 谢谢,正在尝试使用 Xpath 关于 XML 部分的另一个注意事项:考虑一个文件,其中 XML 的格式不是很好的多行,而是所有节点都在一行中......或者类似地,一个 XML 节点内容跨越多行.如果你认为你在这两种情况下都有一个有效的正则表达式,让我们做一些嵌套:"&lt;Notes&gt;this is &lt;SubNote&gt;i'm a hacky sample&lt;/SubNote&gt; sample notes&lt;/Notes&gt;". 使用 xml linq 并使用包含字符串的 where 进行搜索。在使用 Regex 之前始终使用字符串方法。始终使用 eXmlDocument 类、XDocument 类、XmlReader 或 XmlSerialization 解析 xml。 【参考方案1】:

您可以像这样使用XDocument 来解析 XML:

var s = @"<?xml version=""1.0""?>
  <root>
    <Part>this is sample part</Part>
    <Remarks>this is sample remark</Remarks>
    <Notes>this is sample notes</Notes>
    <Desc>sample</Desc>
  </root>";
var document = XDocument.Parse(s);
var names = document.Descendants()
               .Elements()
               .Where(x => x.Value.Contains("sample")) // all nodes with text having sample
               .Select(a => a.Name.LocalName); // return the local names of the nodes
Console.WriteLine(string.Join("\n", names));

打印出来:

同样可以使用 XPath 实现:

var names2 = document.Root.XPathSelectElements("//*[contains(text(), \"sample\")]");
var results = names2.Select(x => x.Name.LocalName));

要在 XML 无效的情况下回退到正则表达式,请使用

<(?:\w+:)?(\w+)[^<]*>[^<]*?sample[^<]*</(?:\w+:)?\1>

请参阅regex demo。注意(?:\w+:)? 匹配打开和关闭标记节点中的任意命名空间。 [^&lt;] 匹配除&lt; 之外的任何字符,因此不会溢出到下一个节点。

【讨论】:

糟糕的是,这个问题是专门关于正则表达式的......仍然这种方法更适合我必须 +1 的工作:) @wiktor 只是一个简单的问题,?性能方面哪个是最好的选择? Linq/正则表达式/Xpath。因为我正在处理大量 XML 文件来搜索文本 当您处理有效的 XML 文件时,我宁愿使用带有 LINQ 的 XML 解析器。如果您必须处理有效或无效的 XML 文件,正则表达式可以提供帮助,速度将取决于内容、XML 大小和运气。注意我每天都必须处理无效的 XML,并且我将正则表达式与 XML 一起使用——但它不是常规的 XML,它是 TMX 文件格式,并且我为它们手动构建了一个特殊的解析器。而且性能还不错。 @WiktorStribiżew 同样在这里,有时我们会收到一些无效的 XML 格式,这就是选择正则表达式来匹配搜索字符串的原因。让我继续使用正则表达式。非常感谢【参考方案2】:

您正在寻找任何标签内的“sample”字符串的完全匹配,而不是包含“sample”作为子字符串的字符串。您可以按以下方式修复您的表达式以获取所有行:

<([\w]+)[^>]*>[a-zA-Z ]*sample[a-zA-Z ]*<\/\1>

【讨论】:

我宁愿使用[^&lt;] 而不是[a-zA-Z ] 占位符...或者只是不贪婪地接受任何东西。这仍然只是对给定示例的修复。使用任意 XML,任何正则表达式都会在某处失败。 一旦sample之前有一个数字或标点符号,由于[a-zA-Z ]*,将不会有任何匹配。 我同意你的看法,它当然不能涵盖所有情况 - 例如,也可能有标点符号等 - 但它给出了问题所在以及如何涵盖特定输入的想法在问题中提供。 @grek40 无论任何字符,它都会发挥作用,感谢输入 ]*>[^

以上是关于正则表达式 包含在 XML 元素中的主要内容,如果未能解决你的问题,请参考以下文章

从 xml 字符串获取结果集元素的正则表达式是啥? [复制]

如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#

用于获取XML元素内容的正则表达式

正则表达式 (C#):匹配 > < 或(非法 XML 字符)但仅当包含在引号内时

XSLT 是不是提供了一种通过使用正则表达式来识别 xml 元素的方法?

XML文件中的C#正则表达式