如何使用正则表达式(lex和yacc)删除所有HTML条件注释?我想删除所有注释,仅保留最后一个HTML标记。
我已经尝试过此正则表达式"<!"(.*?)-->
来获取条件注释,但是它不起作用,我正在寻找与这些条件注释匹配的正则表达式。
"<!"(.*?)-->
这是下面的HTML代码:我正在尝试删除所有注释并仅保留最后一个HTML标记。
<!--[if lte IE 7]>
<html class="ie7 oldie" xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<![endif]-->
<!--[if IE 8]>
<html class="ie8 oldie" xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<![endif]-->
<!--[if gt IE 8]><!-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
<!--<![endif]-->
答案 0 :(得分:0)
这是关于(f)lex正则表达式的两个重要事实。 (有关Flex模式的完整文档,请参见flex manual。该部分不太长。)
在(f)lex中,.
通配符匹配除换行符之外的任何 。换句话说,它等效于[^\n]
。因此"<!".*
仅匹配到行尾。您可以改用(.|\n)
来解决此问题,但请参见下文。
(F)lex不提供非贪婪重复(*?
)。所有重复都延伸到最长的匹配项。因此,(.*?)-->
将与该行的最后一个-->
匹配,(.|\n)*?-->
将与该文件的最后一个-->
匹配。
尽管有点杂乱,但可以编写一个满足您需要的正则表达式:
<!--([^-]|-[^-]|--+[^->])*--+>
应该有效,只要输入文本不以未终止的注释结尾。 (您的模式中的引号是不必要的,因为没有引号的字符对(f)lex没有任何特殊含义,但是它们不会造成伤害。我将它们省略了,因为我认为它们不会使模式变得更难以理解)
重复的序列与以下任何一项匹配:
-
以外的其他字符;或-
后跟另一个-
;或-
,后跟>
以外的其他内容。重复中的最后一种选择可能需要一些解释。潜在的问题是避免输入之类的问题
<!-- Comment with two many dashes --->
如果我们仅将诱人的--[^>]
写为第三种选择,则--->
将不会被视为终止模式,因为---
将与--[^>]
匹配(破折号不是直角括号),然后>
将与[^-]
匹配,并且扫描将继续。添加+
来匹配更长的破折号是不够的,因为(f)lex像许多正则表达式引擎一样,正在寻找最长的整体匹配,而不是每组替代中最长的子匹配。因此,我们需要编写--+[^->]
,它不能匹配---
。
如果不清楚-我可以理解为什么不会-您可以改用start condition来编写一套简单得多的模式:
%x COMMENT
%%
"<!--" { BEGIN(COMMENT); }
<COMMENT>{
"-->" { BEGIN(INITIAL); }
[^-]+ ;
.|\n ;
}
第二条<COMMENT>
规则实际上只是一个效率漏洞;这样可以避免对每个角色触发不操作动作。有了第二条规则,最后一条规则实际上只能匹配单个-
,因此可以这样写。但是完整编写它可以使您删除第二条规则,并向自己证明没有第二条规则即可。
按这样的方式匹配注释的关键见解是(f)lex总是选择最长的匹配,这在某种程度上类似于非贪婪匹配的目标。在<COMMENT>
起始条件之内,-
仅在不能成为更长的-->
匹配项的一部分时,才匹配单字符回退规则。