正则 | 学习笔记
pr1mavera 2019/9/7
笔记
软技能
# 断言
表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。
# 先行断言 x(?=y)
- Lookahead assertion
/x(?=y)/
- 匹配到后面存在
y
的x
/x(?=y)/.test('xy') // true
/Jack(?=Sprat)/.test('JackSprat') // true
/Jack(?=Sprat|Frost)/.test('JackSprat') // true
/Jack(?=Sprat|Frost)/.test('JackFrost') // true
# 负向先行断言 x(?!y)
- Negative lookahead assertion
/x(?!y)/
- 匹配到后面不是
y
的x
// 找到后面不是小数点的数字
'3.124'.match(/\d+(?!\.)/)
// 找到的是 124
# 后行断言 (?<=y)x
- Lookbehind assertion
/(?<=y)x/
- 匹配到存在于
y
后面的x
/(?<=y)x/.test('yx') // true
/(?<=Sprat)Jack/.test('SpratJack') // true
/(?<=Sprat|Tom)Jack/.test('SpratJack') // true
/(?<=Sprat|Tom)Jack/.test('TomJack') // true
# 负向后行断言 (?<!y)x
- Negative Lookbehind assertion
/(?<!y)x/
- 匹配到前面不是
y
的x
// 找到前面不是小数点的数字
'3.124'.match(/\d+(?!\.)/)
// 找到的是 3
# 边界
表示行和单词的开始和结尾。
# 以开头 ^
^A
- 匹配以A开头
# 以结尾 $
A$
- 匹配以A结尾
# 单词边界 \b
- 匹配一个词的边界
'moon'.match(/\bm/) // m
'moon'.match(/oon\b/) // oon
'moon'.match(/\w\b\w/) // null
/\w\b\w/
将不会匹配到任何内容,因为不可能存在这种情况:一个词有字符跟随同时又没有字符跟随
# 非单词边界 \B
- 匹配一个非单词边界
'nooday'.match(/\B.../) // ood
'possibly yesterday'.match(/y\B../) // yes
# 字符类别
用于区分不同类型的字符,例如区分字母和数字。
# 单个字符 .
- 除换行符之外的任何单个字符
'nay, an apple is on the tree'.match(/.n/) // an, on
# 数字 \d
& \D
/\d/
匹配一个数字,等价于/[0-9]/
/\D/
匹配一个非数字,等价于/[^0-9]/
# 单字字符 \w
& \W
/\w/
匹配一个单字字符(字母、数字或者下划线),等价于/[A-Za-z0-9_]/
/\W/
匹配一个非单字字符,等价于/[^A-Za-z0-9_]/
# 空白字符 \s
& \S
/\s/
匹配一个空白字符(空格、制表符、换页符和换行符),等价于/\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff/
/\S/
匹配一个非空白字符,等价于/[^\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/
# 回车符 \r
- 匹配一个回车符
# 换行符 \n
- 匹配一个换行符
# 换页符 \f
- 匹配一个换页符
# 退格 [\b]
- 匹配一个退格
# NULL \0
- 匹配 NULL 字符
- 不要在这后面跟其它小数,因为
\0<digits>
是一个八进制转义序列
# 组和范围
表示表达式字符的分组和范围。
# x|y
- 匹配
x
或者y
# [xyz]
& [a-c]
- 一个字符集合
- 匹配方括号中的任意字符
- 特殊符号在一个字符集中没有特殊的意义,不必进行转义
# [^xyz]
& [^a-c]
- 与
[xyz]
&[a-c]
取反
# (x)
- 捕获括号
- 匹配
x
并且记住匹配项 /(abc) \1/
中对1
进行转义,用于表示被捕获括号匹配的子字符串(这里代表的是abc)- 捕获的内容在字符串中的表现形式是
'$1'
、'$2'
'act act'.match(/(\w+) \1/) // 'act act'
'John Smith'.replace(/(\w+)\s(\w+)/, "$2, $1") // 'Smith, John'
# (?:x)
- 非捕获括号
- 不记住匹配项
# 量词
表示匹配的字符或表达式的数量
# (0-n) *
/x*/
- 匹配前一个表达式 0 次或多次
- 等价于 {0,}
'A ghost boooooed'.match(/bo*/) // booooo
# (1-n) +
/x+/
- 匹配前面一个表达式 1 次或者多次
- 等价于 {1,}
# (0-1) ?
/x?/
- 匹配前面一个表达式 0 次或者 1 次
- 等价于 {0,1}
# (组合) *?
& +?
*
和+
将会不间断的一直匹配下去(mdn上描述为greedy
贪婪地)?
相较来说就是non-greedy
- 两者结合则会产生奇妙的效果,可以理解为有节制的贪婪:
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*>/) // <foo> <bar> new </bar> </foo>
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*?/) // <
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*+/) // <f
'some <foo> <bar> new </bar> </foo> thing'.match(/<.*?a/) // <foo> <ba
# 使用技巧
# 转义
- 使用反斜杠
\
,进行转义 - 普通字符转义之后变成特殊字符
- 特殊字符转义之后变成普通字符
- 反斜杠可以使用反斜杠来转义,识别成普通的反斜杠字符串
# 标志
g
:全局搜索i
:不区分大小写搜索m
:多行搜索s
:允许.
匹配换行符u
:使用unicode码的模式进行匹配y
:执行 “粘性” 搜索,匹配从目标字符串的当前位置开始,可以使用y标志- 标志可组合使用