正则表达式匹配HTML评论中没有的任何内容

时间:2017-02-07 19:04:00

标签: .net regex

首先我要说的是,我知道你永远不应该用正则表达式来解析HTML。我不是,我只是有一个角落案例,评论正在进入我的内容,不幸的是我无法改变它。

我一直在试图想出一个.NET的正则表达式模式,它将匹配任何不属于HTML注释的内容。例如:

foo<!--abc-->bar

应该匹配&#34; foo&#34;和&#34; bar&#34;。

foobar

应该匹配&#34; foobar&#34; (没有评论,所以匹配一切)。

<!--foo-->

不应该产生任何匹配,因为评论中没有任何内容。

我可以很容易地将评论与正则表达式<!--.*?-->匹配,但是根据我的程序规范,在这种情况下我无法简单地删除它们,我需要匹配评论中没有的内容。我能够想到或在网上找到尝试排除评论的每一种方式都会最终选择所有内容(因为那时评论的开头和结尾都不是比赛的开始和结束),或发现不受欢迎的匹配。例如:

foo<!--abc-->bar

使用正则表达式((?!<!--.*?-->).)*(通过使用否定前瞻来简单地否定正则表达式来查找注释),我得到4个匹配:第一个是正确匹配的&#34; foo&#34;,然后是第二个第四场比赛显示为空白字符串(我不知道为什么),第三场比赛是&#34;! - abc - &gt; bar&#34;,因为只需删除&#34;&lt; &#34;技术上满足条件。让最后的*量词懒惰似乎使它更糟糕,返回17个空白字符串匹配。我尝试过其他一些方法,例如使用否定的外观来排除评论,但他们都成了类似问题的牺牲品,我不确定如何解决。

我也尝试过这个问题的正则表达式:[{3}};但不幸的是,这包括匹配中评论的<!---->部分,如果我正确阅读,我认为它不会匹配没有字符串的字符串评论。我尝试修改这个以解决我的用例的这些问题,但是没有取得任何成功......

修改

在退出问题并重新考虑我的需求之后,我意识到我实际上并不需要匹配所有不属于评论的文本。我真的只需要知道是否有任何非空白文本不是评论的一部分,在内容的任何地方,使用Regex.IsMatch方法和SingleLine选项。为此目的,以下正则表达式应该可以解决这个问题:

(?!^(\s*<!--([^-]*|-[^-]*|--[^>]*)-->\s*)+$)^.*\S.*$

由于这大大改变了问题并立即回答了问题,我现在还不确定正确的协议是什么......但除非提出更好的建议,否则我想我会将问题留待几天,以防任何人碰巧在我的正则表达式中发现错误,如果没有人,我只会自我回答并关闭问题。

1 个答案:

答案 0 :(得分:1)

如果匹配和cpaturing变得复杂,在某些情况下a simple "trick"会有所帮助:
匹配您不想要的内容(在替换的左侧)|或{{3}你需要什么。

您不想要的是评论:<!--.*?-->

捕获任何未开始发表评论的字符:|((?:(?!<!--).)+)
capture可防止跳过<!--)并抓取捕获第一个捕获组。

(?s)<!--.*?-->|((?:(?!<!--).)+)

lookahead使用(?s)(点也与换行符匹配)。请参阅single-line mode

在PCRE正则表达式中,可以在不通过this demo at regexstorm动词(use of (*SKIP)(*F))捕获组的情况下完成。