regex-tuesday,每周二会出一道正则表达式的题目,本周的题目比较简单,如果你答出来了,可以留言,如果答不出来.可以看看我的答案和解释.下面内嵌了原题目页面.你要做的就是使用JavaScript正则字面量的写法/regex/i,来通过所有的测试用例.本周题目的具体要求是把用例文本中第二次出现的相同行按规则在左右两侧各添加两个星号,一共有两个文本框需要填写,左边的写替换正则,右边的写替换结果.相当于使用"xxoo".replace(/xx/,"oo").
查看答案
这个题目主要考察捕获分组.
1.匹配左边的文本
首先应该写出匹配左边文本第一行的正则,由于用到了$锚点,所以得使用多行模式m:
从第二行中开始有重复行,所以必须用到捕获分组和反向引用.
2.开始替换
最先尝试:
/^(. .+)$\n\1/m 替换为 $1\n$1 //匹配情况3/10
发现\n并不能显示为换行符,于是需要捕获前面的换行符:
/^(. .+)$(\n)\1/m 替换为 $1$2$1 //匹配情况3/10
在适当的地方加上星号:
/^(. .+)$(\n)\1/m 替换为 $1$2* *$1** //匹配情况3/10
发现左边的两个星号后面多了个空格.需要再细化一下$1,添加一个捕获分组:
/^(. (.+))$(\n)\1/m 替换为 $1$3* **$2** //匹配情况6/10
第五个用例没有通过,是因为它需要两次替换,于是加上g选项:
/^(. (.+))$(\n)\1/mg 替换为 $1$3* **$2** //匹配情况7/10
第八个用例错误的多匹配了一个,需要给匹配正则的第二行加上$锚点:
/^(. (.+))$(\n)\1$/mg 替换为 $1$3* **$2** //匹配情况8/10
第九个用例没有匹配,是因为左侧的第二行文本开始处有两个空格,这次我们需要大改正则,把不定长的空格也放到一个捕获分组中并替换到右侧:
/^(. (.+))$(\n)\S+(\s+)\2$/mg 替换为 $1$3*$4**$2** //匹配情况9/10
第十个用例没有匹配,是因为忽略大小写的问题,于是加上i选项:
/^(. (.+))$(\n)\S+(\s+)\2$/mgi 替换为 $1$3*$4**$2** //匹配情况9/10
居然还是不成功,仔细一看,原来是匹配的结果必须是第二行中的原始数据(大写),而不是第一行的数据.于是我们还需要将反向引用\2放到一个捕获分组中:
/^(. (.+))$(\n)\S+(\s+)(\2)$/mgi 替换为 $1$3*$4**$5** //匹配情况10/10
再看看有没有多余的捕获分组,有的话需要去掉或者替换成非捕获分组.1到5都有用,那就不用去了.