正则字符类中点号匹配异常求助:<>&为何被正则匹配?
嘿,咱们来一步步拆解你遇到的这两个问题,核心其实是正则字符类里连字符-的坑,不是点号的问题哦:
疑问1:字符类[]中的点号.为何并非仅匹配字面量点号?
你其实误解了点号在字符类里的行为——在[]内部,.就是单纯匹配字面量的点号,没有任何特殊含义。问题出在你写的[a-zA-Z0-9.-_+]里的**.-_这一段**:
在正则字符类中,-这个符号很特殊:如果它既不在字符类的开头/结尾,也没有被转义,它就会变成范围定义符,表示匹配「左边字符到右边字符之间的所有ASCII字符」。.的ASCII码是46,_的ASCII码是95,所以.-_实际上是匹配ASCII码46到95之间的所有字符——这可远不止.、-、_,还包括<、>、=、?等等一堆符号(比如<的ASCII是60,正好落在46-95这个区间里)。
所以不是点号没匹配字面量,是这个范围把一堆额外字符都包含进来了,让你误以为点号在字符类里有特殊作用。
疑问2:为何<>&字符会被该正则表达式匹配?移除点号后则不再匹配段落标签?
刚才已经说过了,<属于.-_这个范围里的字符(ASCII 60在46-95之间),所以你的正则里的第一个字符类[a-zA-Z0-9.-_+]+会把<p>里的<、p、>全匹配上——因为这些字符都在范围里,直到遇到@才会停止匹配前面的部分,最终结果自然就包含了<p>的开头。
当你移除点号后,字符类变成[a-zA-Z0-9-_+],如果这时候你顺便把-移到了字符类的开头或结尾(比如写成[a-zA-Z0-9_+-]),-就变成了字面量的连字符,不再定义范围,字符类里就只有字母、数字、_、+、-这几种字符,<>自然就不在匹配范围内了,所以不会再把段落标签的部分包含进来。
最后给你个修正建议:如果想在字符类里同时包含.、-、_,最好把-放在字符类的开头或结尾,或者转义它,比如写成[a-zA-Z0-9._+-]或者[a-zA-Z0-9.\-_+],这样就不会出现意外的范围匹配了。
内容的提问来源于stack exchange,提问作者d-_-b

