[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, ",")