使用多行无法使正则表达式正常工作

我有一个来自应用程序的非常大的XML输出。 我需要使用我的程序处理它,然后将其反馈给原始程序。 这个XML中的部分需要填写我们的替换。 有趣的部分看起来像这样:

 value here are some other tags value  

该文件包含几个这样的部分。

我需要在这些标记内部获取所有XML部分才能对其进行修改。 我写了一个正则表达式来获取这些碎片,但它不起作用:

 XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"output.xml"); Regex regExp = new Regex(@"(.*?)", RegexOptions.Multiline & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant); MatchCollection matches = regExp.Matches(xmlDoc.InnerXml); 

如果我将所有内容放在一行中并在没有多行选项的情况下调用此正则表达式,它确实会发现每个出现的情况。 通过保留文件并设置多行选项,它不起作用。 有什么问题,我应该改变什么? 或者有没有更简单的方法来获得这些标签之间的XML部分没有正则表达式?

我相信使用的选项是RegexOptions.Singleline而不是RegexOptions.Multiline ( src )。 允许(。)匹配换行符应该适用于您的情况。

…点也匹配换行符的模式称为“单行模式”。 这有点不幸,因为很容易将这个术语与“多线模式”混淆。 多行模式仅影响锚点,单行模式仅影响点…当使用.NET框架的正则表达式类时,通过指定RegexOptions.Singleline激活此模式,例如在Regex.Match(“string”中“,”正则表达式“,RegexOptions.Singleline)。

RegExp对于xml来说是一个糟糕的工具……难道你不能将它加载到XDocument / XmlDocument中并使用xpath吗? 如果你澄清你想要做的修改,我希望我们可以填补空白…在这种情况下命名空间可能是使它变得复杂的主要因素,所以我们只需要使用XmlNamespaceManager

这是一个被授予的例子,比仅仅是一个正则表达式更复杂 – 但是,我希望它可以更好地应对xml的细微差别:

  string xml = @" value here are some other tags value "; XmlDocument doc = new XmlDocument(); doc.LoadXml(xml); XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable()); mgr.AddNamespace("sys", "foobar"); var matches = doc.SelectNodes("//sys:customtag[@sys:type='Processtart']", mgr); foreach (XmlElement start in matches) { XmlElement end = (XmlElement) start.SelectSingleNode("following-sibling::sys:customtag[@sys:type='Procesend'][1]",mgr); XmlNode node = start.NextSibling; while (node != null && node != end) { Console.WriteLine(node.OuterXml); node = node.NextSibling; } } 

正则表达式字符“。” 即使设置了MultiLine选项,也永远不会匹配换行符。 相反,你应该使用[\s\S]或其他任何与之匹配的组合。

MultiLine选项仅修改^(行首字符串而不是字符串开头)和$(行尾而不是字符串结尾)的行为

顺便说一句:确实,正则表达式不是扫描HTML的正确方法……

如果您仍然遇到此问题,可能是因为您使用的是RegexOptions而不是OR。

此代码是错误的,并将作为第二个参数传递给构造函数:

 Regex regExp = new Regex(@"(.*?)", RegexOptions.Multiline & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant); 

此代码是正确的(就使用多个RegexOptions标志而言):

 Regex regExp = new Regex(@"(.*?)", RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant);