问题的来源
首先说一下引发我对这个正则中的中括号重新认识的问题吧。今天在读同事代码的时候,在做一个获取url最后的文件名时,他大概是这么写的
let name = url.match(/([^/]*).html?/)[1]
首先纠结的点是 [^/]* (后来发现是自己脑子不好使了),我理解成了匹配^或者/任意多次,但是结果name却是正确的,感觉世界崩塌了,怎么会这样?
然后去查菜鸟教程,原来中括号里^是排除的意思,然后觉得自己理解了这个正则的意思: 匹配一个字符串中不以/开头但是以.html结尾的最长的字符串。
但是再一看, 不对啊/([^/]*).html?/ 的前连个/不是已经配对成了一个正则了吗? 这不是语法错误吗? 什么鬼啊?
我的世界观又被颠覆了,难道中括号里的/是作为一个普通字符存吗吗?
然后我又试一试如下这些元字符:
元字符“.”不能匹配任何字符了,而是只能匹配自身,而且转移与否表现一致;
元字符“*”不转义也可以单独使用匹配自身;
其他的一些元字符也表现一样。
到此我终于可以下了一个结论:
任何元字符,只要放在中括号里,就只能代表字符本身,而不再具有其作为元字符的功能
在我验证这个结论的时候,使用了一些极端的例子,然后抛了一个错误:
原来我的结论是有毛病的,“-”这个字符就比较有意思,它会根据自身前后来判断他的意义,如果“-”前后不是同时有字符,那么它就代表“-”本身,如果“-”前后都有字符,那么前后字符和“-”共同代表一个范围的字符,这个然后有“-”前后的ascii码决定。
上图中报错就是因为“-”前后有字符,但是因为“-”前的a的ascii码大于后面的A所有报错说:Range out of order in character class(字符顺序错误)。
当然上面的结论还有很多漏洞,比如 “^” 不是代表它本身,而是功能发生转变了,如果要在中括号里匹配 “^”, 就必须转义“\^”。