前言
本文旨在记录常用的正则表达式,方便查找。
通过标志进行高级搜索
| 标志 | 描述 |
|---|---|
g | 全局搜索。 |
i | 不区分大小写搜索。 |
m | 多行搜索。 |
s | 允许 . 匹配换行符。 |
u | 使用 unicode 码的模式进行匹配。 |
y | 执行“粘性 (sticky)”搜索,匹配从目标字符串的当前位置开始。 |
捕获括号 与 \1 \2 $1 $2
模式 /(foo) (bar) \1 \2/ 中的 '(foo)' 和 '(bar)' 匹配并记住字符串 "foo bar foo bar" 中前两个单词。
模式中的 \1 和 \2 表示第一个和第二个被捕获括号匹配的子字符串,即 foo 和 bar,匹配了原字符串中的后两个单词。注意 \1、\2、...、\n 是用在正则表达式的匹配环节。
而在正则表达式的替换环节,则要使用像 $1、$2、...、$n 这样的语法,例如,'bar foo'.replace(/(...) (...)/, '$2 $1')。
$& 表示整个用于匹配的原字符串。
按大写字母拆分字符串
将下列英文单词转数字。
const str = 'SixOneThreeOneZero';
最关键的是要正确拆分上述字符串,再通过映射关系转换。
通过正则拆分字符串:
const str = 'SixOneThreeOneZero';
// 此处的(?=)表示非捕获括号,必须带括号。
const re = /(?=[A-Z])/;
str.split(re); // [ 'Six', 'One', 'Three', 'One', 'Zero' ]
// 匹配过程解析:
// 1. ?= 正向断言,匹配的是捕获字符前面的字符串。
// 2. 第一个字符S,捕获成功,匹配的x==='',继续向后匹配,直到下一个捕获
// 3. 下一个捕获为O,x === '',...直到最后一个
// 4. 然后通过split按匹配到的x进行拆分。
/(?=[A-Z])/ 表示:匹配后面跟着 A-Z 的 ''。
x(?=y)匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。x(?!y)仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。(?<=y)x匹配'x'仅当'x'前面是'y'.这种叫做后行断言。(?<!y)x仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。
通过match检索字符串:
const str = 'SixOneThreeOneZero';
// 注意这里要加 g
const re = /[A-Z][a-z]+/g;
str.match(re); // ['Six', 'One', 'Three', 'One', 'Zero']
将ip地址中的0去掉
192.168.255.001 === 192.168.255.1
'192.168.255.001'.replace(/(?<=\.)0+/, ''); // '192.168.255.1'
'190.108.255.001'.replace(/(?<=\.)0+/, ''); // '190.108.255.1'
正则目标是:只匹配 . 后面紧跟的 0,这里是 1 到 2 个 0,用 0+。
(?<=) 表示后行断言,且为非捕获括号(即\1 \2 $1 $2 不捕获该括号)。.需要转义 \.
需要 +g,不加只能匹配一个。
'1.01.001.1'.replace(/(?<=\.)0+/g, ''); //'1.1.1.1'
'1.01.001.1'.replace(/(?<=\.)0+/, ''); // '1.1.001.1'
001.1.1.1 上述正则无法覆盖此字符串。
换个思路,匹配数字前面的多个0。
'001.01.001.001'.replace(/0+(?=[1-9])/g, ''); // '1.1.1.1'
'001.01.001.101'.replace(/0+(?=[1-9])/g, ''); // '1.1.1.11' 依然有问题
再想想: 0 前面如果不是 1-9 就全替换掉
'001.01.001.201'.replace(/(?<![1-9])0+/g, ''); // '1.1.1.201'
小结:
- 匹配
.需要转义\.- 后行断言:
(?<=)(?<!)
常用正则
- 匹配
:的字母,加上双引号。
// 匹配:
([a-z]+)(?=:)
// 替换
\"$1\"
匹配空白字符
/\s/ // 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
/\x20/ // 匹配一个空格。
/\f/ // 匹配一个换页符。
/\n/ // 匹配一个换行符。
/\r/ // 匹配一个回车符。