PHP移除HTML注释:为何preg_replace执行后仍残留尖括号?
这个问题的核心在于你对preg_replace的正则表达式语法要求理解有误,导致实际执行的匹配逻辑和你预期的完全不一样:
正则表达式必须用分隔符包裹
preg_replace的第一个参数要求是被分隔符(比如/、#、~)包裹的正则模式,但你传入的是'<!--hello//-->'(或是未转义的'<!--hello//-->',取决于你的代码是否被HTML转义)。PHP会自动把字符串的第一个字符当作分隔符——比如如果是未转义的模式,第一个字符是<,它会尝试寻找下一个<作为结束分隔符,但你的模式里没有第二个<,PHP会触发警告,同时尝试解析剩余内容。正则中的注释语法截断了你的匹配模式
不管你的模式是转义后的还是原始的,里面都包含//——在正则表达式语法中,//表示单行注释的开始,从//到模式末尾的所有内容都会被正则引擎忽略。也就是说,你的实际匹配模式被截断成了<!--hello(原始模式)或者lt;!--hello(转义后的模式),根本不会匹配到完整的<!--hello//-->(或其转义后的字符串)。不完整的匹配导致残留字符
因为你的模式只匹配了目标片段的前半部分,替换为空后,原本的完整注释片段就只剩下了未被匹配的后半部分(比如原始模式下的//-->,或是转义后的模式下的>)。你看到的<>(或<>),其实是原本片段的开头部分(比如<或<)加上未被匹配替换的结尾部分(比如>或>)组合而来的。
简单来说:你写的内容没有被当作完整的目标字符串来匹配,正则引擎因为分隔符和注释语法的问题,只识别了部分匹配规则,自然无法替换掉你想要的整个片段,留下了残留的尖括号(或其实体)。
内容的提问来源于stack exchange,提问作者Nick Manning

