现象: '-' 字符在正则中位置不同,匹配的结果也不同(预期应该都能匹配上)
代码如下:
第一种位置: 匹配结果是false
const reg = /^[\w\.-:\u4e00-\u9fa5]{1,128}$/g;
reg.test('-'); // console: false
第二种位置: 匹配结果是true
const reg1 = /^[\w-\.:\u4e00-\u9fa5]{1,128}$/g;
reg1.test('-'); // console: true
查了相关资料, 也没有涉及到字符位置顺序这一块的
###这是因为字符-
在正则表达式的字符集合[]
中,可能表示的是元子符,作用是连字符,表示左边字符到右边字符的一个范围,比如[0-9]
等价于[0123456789]
,这里的-
表示的就是一个连字符的意思。
在你的例子/^[\w-.:\u4e00-\u9fa5]{1,128}$/g
中,由于\w
表示的是一个字符集合,表示单词字符集合,在ASCII码的环境下,等价于[0-9a-zA-Z_]
,因此,你的[\w-.:\u4e00-\u9fa5]
也就等价于[_0-9a-zA-Z-.:\u4e00-\u9fa5]
,由于这里的-
前面的Z已经和A配对成一个整体A-Z
了,所以-
的左边没有可以用来组合成一个表示范围的整体了,就只表示了自己本来的意思,只表示一个普通的字符-。所以这里的^[\w-.:\u4e00-\u9fa5]{1,128}$
会匹配字符串-
。
而在你的正则^[\w.-:\u4e00-\u9fa5]{1,128}$
中,由于这里的[.-:]
表示的是一个整体,意思是匹配从.
到:
这个范围的任意一个字符,匹配的字符如下:
所以这个正则匹配不到字符-
正常情况下,你如果要使[]
里面的连字符-
失去特殊符号的作用,可以把它放在第一个位置,如[-az]
,或者转义一下[a\-z]
,这两个正则都是只匹配-
、a
、z
这三个字符中的任意一个。
[abcd]
匹配方括号中的任意字符 破折号(-)来指定一个字符范围,它并不是指匹配字符-
本身。由于abcd这些字符范围顺序是连续的,[abcd]
和[a-d]
是一样的。若想匹配-
可以这样[a\-b]
此时它与[ab\-]
是同样意思,都只是表示匹配字符a
或 b
或 -
老鼠拧刀满街找猫已经正解了,这里稍稍补充下。
- 中括号
[]
里的字符集是无序的,并且字符集里的字符如果是特殊字符当做普通字符使用时记得转义(忘记转义也是经常犯的错误,错了几次就记住了)。 - 关于连字符
-
的使用规则可以参考Regular-Expressiongs.info -字符集 :
The hyphen can be included right after the opening bracket, or right before the closing bracket, or right after the negating caret. Both [-x] and [x-] match an x or a hyphen. [^-x] and [^x-] match any character that is not an x or a hyphen. This works in all flavors discussed in this tutorial. Hyphens at other positions in character classes where they can’t form a range may be interpreted as literals or as errors