正则表达式是匹配模式,要么匹配字符,要么匹配位置。
匹配位置相关知识点内容包括:
什么是位置?
如何匹配位置?
位置的特性
1、什么是位置?
位置(锚)是相邻字符之间的位置。
2、如何匹配位置?
在ES5中,共有6个锚:^、$、\b、\B、(?=p)、(?!p)
2.1 ^ 和 $
^ (脱字符)匹配开头,在多行匹配中匹配行开头。(Begin)
$ (美元符号)匹配结尾,在多行匹配中匹配行结尾。(End)
比如我们把字符串的开头和结尾用 "#" 替换(位置可以替换成字符的!):
var result = "hello".replace(/^|$/g, '#');
console.log(result); // "#hello#"
多行匹配模式(即有修饰符 m)时,二者是行的概念,这一点需要我们注意:
var result = "I\nlove\njavascript".replace(/^|$/gm, '#');
console.log(result);
/*
#I#
#love#
#javascript#
*/
2.2 \b 和 \B
\b 是单词边界,具体就是 \w 与 \W 之间的位置,也包括 \w 与 ^ 之间的位置,和 \w 与 $ 之间的位置。(WordBoundary)
比如考察文件名 "[JS] Lesson_01.mp4" 中的 \b,如下:
var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(result);
// "[#JS#] #Lesson_01#.#mp4#"
\B 就是 \b 的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉 \b,剩下的都是 \B 的。(NonWordBoundary)
具体说来就是 \w 与 \w、 \W 与 \W、^ 与 \W,\W 与 $ 之间的位置。
比如上面的例子,把所有 \B 替换成 "#":
var result = "[JS] Lesson_01.mp4".replace(/\B/g, '#');
console.log(result);
// "#[J#S]# L#e#s#s#o#n#_#0#1.m#p#4"
2.3 (?=p) 和 (?!p)
(?=p),其中 p 是一个子模式,即 p 前面的位置,或者说,该位置后面的字符要匹配 p。(Followed by P)
比如 (?=l),表示 "l" 字符前面的位置,例如:
var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// "he#l#lo"
而 (?!p) 就是 (?=p) 的反面意思(Not followed by p),比如:
var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// "#h#ell#o#"
3、位置的特性
对于位置的理解,我们可以理解成空字符 ""。
比如 "hello" 字符串等价于如下的形式:
"hello" == "" + "h" + "" + "e" + "" + "l" + "" + "l" + "" + "o" + "";
也等价于:
"hello" == "" + "" + "hello"
因此,把 /^hello$/ 写成 /^^hello$$$/,是没有任何问题的:
var result = /^^hello$$$/.test("hello");
console.log(result); // true
甚至可以写成更复杂的:
var result = /(?=he)^^he(?=\w)llo$\b\b$/.test("hello");
console.log(result); // true
也就是说字符之间的位置,可以写成多个。
***TIP *** 把位置理解成空字符,是对位置非常有效的理解方式。