正则表达式笔记(二)-位置匹配

148 阅读1分钟

[JS正则迷你书作者](老姚 的个人主页 - 动态 - 掘金 (juejin.cn))

[JS正则迷你书](《JavaScript 正则表达式迷你书》问世了! - 知乎 (zhihu.com))

位置匹配

正则表达式要么匹配字符要么匹配位置。

位置(锚)是相邻字符之间的位置。

6个锚

var regex = /^$\b\B(?=a)(?!b)/g
// ^    $   \b  \B  (?=p)   (?!p)

图片截自正则迷你书

^和$

^(脱字符) 匹配开头,在多行匹配中匹配行开头。

$(美元符号) 匹配结尾,在多行匹配中匹配行结尾。

比如我们把字符串的开头和结尾用"#"替换(位置可以替换成字符):

var result = "hello".replace(/^|$/g, '#');
console.log(result);
// => "#hello#"

多行匹配模式(即有修饰符m)时,二者是行的概念,这一点需要我们注意:

var result = "I\nlove\njavascript".replace(/^|$/gm, '#');
console.log(result);
/*
#I#
#love#
#javascript#
*/

\b和\B

\b是单词边界,具体就是\w与\W之间的位置(注意是单词包含数字、字母和下划线),也包括\w与^之间的位置,和\w与$之间的位置。

图片截自个人文档

var result = "[JS] Lesson_01.mp4".replace(/\b/g, '#');
console.log(result);
// => "[#JS#] #Lesson_01#.#mp4#"

在字符串中所有位置中,扣掉\b,剩下的都是\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"

(?=p) 和 (?!p)--先行断言

(?=p),其中p是一个子模式,即p前面的位置,或者说,该位置后面的字符要匹配p。

var result = "hello".replace(/(?=l)/g, '#');
console.log(result);
// => "he#l#lo"

而(?!p)就是(?=p)的反面意思:

var result = "hello".replace(/(?!l)/g, '#');
console.log(result);
// => "#h#ell#o#"

二者的学名分别是 positive lookahead 和 negative lookahead。

中文翻译分别是正向先行断言负向先行断言

ES5 之后的版本,会支持 positive lookbehind 和 negative lookbehind。

具体是 (?<=p)(?<!p)

对于位置的理解,我们可以理解成空字符""。

实例

不匹配任何东西的正则
var regex = /.^/
// 要求有一个字符,他后边是开头,这样的是不存在的
数字的千位分隔符表示法
// 先匹配出最后一个逗号
var result = "12345678".replace(/(?=\d{3}$)/g, ",")
​
// 再匹配所有的逗号
var result = "12345678".replace(/(?=(\d{3})+$)/g, ",")
​
// 开头不出现,使用 (?!p),即 (?!^)
var result = "123456789".replace(/(?!^)(?=(\d{3})+$)/g, ",")
​
// 其他形式
var string = "123456789 123456789"
var result = string.replace(/(?!\b)(?=(\d{3})+$)/g,  ",")
// \w与\W之间不能有逗号,也就是空格与1之间的位置、开头与1之间的位置(\w与\W之间的位置,单词与非单词之间的位置)
// (?!\b) == \B 单词与单词之间的位置:3和4、6和7
var result = string.replace(/\B(?=(\d{3})+$)/g,  ",")