由于注释不能嵌套在 HTML 中,理论上,正则表达式可以完成这项工作。尽管如此,使用某种解析器将是更好的选择,尤其是在您的输入不能保证格式正确的情况下。
这是我的尝试。要仅匹配普通评论,这将起作用。它已经变成了一个怪物,对此感到抱歉。我已经对它进行了广泛的测试,它似乎做得很好,但我不做任何保证。
<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->
解释:
<!-- #01: "<!--"
(?! #02: look-ahead: a position not followed by:
\s* #03: any number of space
(?: #04: non-capturing group, any of:
\[if [^\]]+] #05: "[if ...]"
|<! #06: or "<!"
|> #07: or ">"
) #08: end non-capturing group
) #09: end look-ahead
(?: #10: non-capturing group:
(?!-->) #11: a position not followed by "-->"
. #12: eat the following char, it's part of the comment
)* #13: end non-capturing group, repeat
--> #14: "-->"
步骤#02 和#11 至关重要。#02 确保以下字符不表示条件注释。之后,#11 确保后面的字符不表示注释的结尾,而 #12 和 #13 导致实际匹配。
应用“global”和“dotall”标志。
做相反的事情(只匹配条件注释),它会是这样的:
<!(--)?(?=\[)(?:(?!<!\[endif\]\1>).)*<!\[endif\]\1>
解释:
<! #01: "<!"
(--)? #02: two dashes, optional
(?=\[) #03: a position followed by "["
(?: #04: non-capturing group:
(?! #05: a position not followed by
<!\[endif\]\1> #06: "<![endif]>" or "<![endif]-->" (depends on #02)
) #07: end of look-ahead
. #08: eat the following char, it's part of the comment
)* #09: end of non-capturing group, repeat
<!\[endif\]\1> #10: "<![endif]>" or "<![endif]-->" (depends on #02)
同样,应用“global”和“dotall”标志。
步骤#02 是因为“downlevel-revealed”语法,请参阅:“MSDN - About Conditional Comments”。
我不完全确定允许或预期的空间。在适当的地方添加\s*
到表达式中。