正则表达式 包含在 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 节点内容跨越多行.如果你认为你在这两种情况下都有一个有效的正则表达式,让我们做一些嵌套:"<Notes>this is <SubNote>i'm a hacky sample</SubNote> sample notes</Notes>"
.
使用 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+:)?
匹配打开和关闭标记节点中的任意命名空间。 [^<]
匹配除<
之外的任何字符,因此不会溢出到下一个节点。
【讨论】:
糟糕的是,这个问题是专门关于正则表达式的......仍然这种方法更适合我必须 +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>
【讨论】:
我宁愿使用[^<]
而不是[a-zA-Z ]
占位符...或者只是不贪婪地接受任何东西。这仍然只是对给定示例的修复。使用任意 XML,任何正则表达式都会在某处失败。
一旦sample
之前有一个数字或标点符号,由于[a-zA-Z ]*
,将不会有任何匹配。
我同意你的看法,它当然不能涵盖所有情况 - 例如,也可能有标点符号等 - 但它给出了问题所在以及如何涵盖特定输入的想法在问题中提供。
@grek40 无论任何字符,它都会发挥作用,感谢输入 ]*>[^以上是关于正则表达式 包含在 XML 元素中的主要内容,如果未能解决你的问题,请参考以下文章
从 xml 字符串获取结果集元素的正则表达式是啥? [复制]
如何使用正则表达式匹配从 xml 文件中搜索和替换包含占位符标记的文本。 VB.net 或 C#
正则表达式 (C#):匹配 > < 或(非法 XML 字符)但仅当包含在引号内时