Javascript的正则表达式虽然很早以前就接触过了,那时候还在做编辑的时候,用AS写了一个文本替换的小程序。
最近逛书店,发现有本21天学通XXX的系列书,一向对这种名字的书没有好感,不过还是很好奇地拿了起来,随便翻了一下,正好看到一些以前没有注意到的地方,回来继续查看犀牛书等书补充了一下。
capturing groups(捕获性分组,犀牛书上叫组合)。
这个最常见的,就是用括号把一部分表达式包起来,方便在后面用+
或者*
或者{n,m}
等来表示数量等,又或者有时候要用到|
的情况。
non capture group (非捕获性分组,犀牛书上叫只组合)
和捕获性分组的区别就是,这里的括号内的内容不被计算入分组,也就是说是不存入$1,$2这些里面的。
lookahead (零宽度正预测先行断言、先行断言)
匹配x当且仅当x后面紧跟y。
例如,/Jack(?=Sprat)/
匹配 'Jack' 当且仅当后面是'Sprat'。 /Jack(?=Sprat|Frost)/
匹配 'Jack' 当且仅当后面是 'Sprat' 或 'Frost' 。然而,无论 'Sprat' 还是 'Frost' 都不会进入匹配的结果里面,就好像宽度为0一样。
::: warning 注意
lookhehind(零宽度正回顾后发断言、后行断言)在Javascript中是不支持的!也就是说,如果想要匹配java开头的script,是不能使用/(?<java)script/
来匹配的。
:::
negated lookahead(零宽度负预测先行断言、负向先行断言)
匹配 'x' 当且仅当 'x' 后面不是 'y'.
例如,/\d+(?!.)/ 匹配一个数字当且仅当后面跟的不是一个小数点。/\d+(?!.)/.exec("3.141") 匹配 '141' 而不是 '3.141'。
n为正整数
和第n个分组第一次匹配的字符
相匹配。
例如,想要/(['"]).*?\1/,可以匹配成对引号的内容。意思就是"abc'是不会被匹配的,只有"abc"或者'abc'可以。后面的\1必须和前面第一个捕获的内容一模一样。
前者根本就不进入匹配,当然也不进入捕获的分组了;后者会进入匹配,不过不进入捕获分组。
例如,/boy(?=z)/
表示的是后面有z字母的boy,即boyz这样的形式的boy满足条件,如果是boy zh 或者boy and 则不匹配,但是!即使是boyz,在捕获的结果里面,z是完全不会出现的;/boy(?:z)/
会捕获到整个boyz,而且结果中也是boyz,只不过z不会出现在分组中,也就是$1 != 'a'
使用new的形式新建正则表达式的话,对于反斜杠(backsplash)稍微麻烦一点。
例如, var r=/\\/
用new的话,需要写成下面的形式:
var r= new RegExp('\\\\');
为什么呢,因为new的话,第一个参数是一个字符串,而字符串里面也是支持反斜杠转义的!
比如 'lm\no'
实际上不是lm反斜杠no
,而是lm换行o
,要达到目的,需要写成'lm\\no'
回到上面的,/\\/
这个表示一个反斜杠字符,其本身是含有两个\
的正则表达式,所以当里面的两个反斜杠转换成字符串就是四个反斜杠啦!
PS:正则表达式中/
不需要转义,所以字符/
用///
的正则表达式来表示,同时/
字符不需要转义,用new来新建时候直接写作new RegExp('/')
。
参考资料: