【问题标题】:Regex.Split returning whitespacesRegex.Split 返回空格
【发布时间】:2015-12-14 12:38:37
【问题描述】:

我想在我的 ASP.NET 页面上将视图作为 HTML 文档导出给用户。我想提供只获取部分视图的选项。

因此,我想用Regex.Split() 拆分输出。我写了一个正则表达式来匹配我想要删掉的部分。拆分后,我再次将 2 个输出部分放在一起。

问题是我得到了一个包含 3 个部分的列表,其中第二个包含 " "。如何更改输出仅包含 2 个字符串的代码?

我的代码:

textParts = Regex.Split(text, @"<!--Graphic2-->(.|\n)*<!--EndDiscarded-->");
text = textParts[0] + textParts[1];

text 包含 HTML、CSS 和 jQuery 代码。我在要剪掉的块周围写了&lt;!--Graphic2--&gt;之类的cmets。

编辑

我现在使用Regex.Replace() 方法让它工作了。但我仍然不知道为什么 Split 没有按我的预期工作。

【问题讨论】:

  • 仅供参考,您可以使用RegexOptions.Singleline 使.(点)匹配换行符。
  • (.|\n)* 是一个非常糟糕的模式,涉及很多回溯并导致灾难性的回溯问题。带有. 的单行标志是对任何符号使用贪婪匹配的正确方法。但是,既然你处理的是 HTML,我宁愿你试试 HTML 解析工具。
  • @juharr 谢谢你,我要改变它。
  • 或者您可以使用[\s\S]* 代替(.|\n)*
  • 我认为它甚至会更快/更容易迭代行并在您在一行中看到一个部分的开头并在找到结尾时停止时立即开始捕获... HTML解析和正则表达式似乎都无法完成这项任务。

标签: c# asp.net regex split


【解决方案1】:

您应该考虑使用适当的工具解析 HTML,例如 HtmlAgilityPack

当前的问题是关于为什么Regex.Split 返回 3 个值。这是由于您的模式中存在捕获组。 Regex.Split 返回字符串开始/结束与匹配块之间的块,所有捕获的子字符串:

如果在Regex.Split 表达式中使用了捕获括号,则任何捕获的文本都将包含在结果字符串数组中。例如,如果将字符串“plum-pear”拆分到位于捕获括号内的连字符上,则返回的数组包含一个包含连字符的字符串元素。

所以,Regex.Split(text, @"&lt;!--Graphic2--&gt;(.|\n)*&lt;!--EndDiscarded--&gt;") 匹配 &lt;!--Graphic2--&gt; 子字符串,然后匹配并捕获到组 1 任何 0+ 出现的任何字符,尽可能多,然后匹配 &lt;!--EndDiscarded--&gt;") - 这些匹配被删除并返回不匹配的子字符串,但也返回捕获到重复捕获组中的最后一个字符。

因此,如果您打算在此任务中使用正则表达式,您应该考虑将其重写为@"(?s)&lt;!--Graphic2--&gt;.*?&lt;!--EndDiscarded--&gt;"@"&lt;!--Graphic2--&gt;[^&lt;]*(?:&lt;(?!!--EndDiscarded)[^&lt;]*)*&lt;!--EndDiscarded--&gt;",这样效率会更高,甚至是@"&lt;!--Graphic2--&gt;[^&lt;]*(?:&lt;(?!!--(?:EndDiscarded|Graphic2))[^&lt;]*)*&lt;!--EndDiscarded--&gt;",这将确保没有嵌套的Graphic2 cmets 匹配。

看,当您想确保您的模式更高效、更安全地工作时,正则表达式的复杂性会增加。然而,即使是这些较长的版本也不能保证 100% 的安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多