字符 | 描述 |
---|---|
* | 匹配前面的子表达式零个或者多个,等价于{0,} |
+ | 匹配前面的表达式一个或者多个 等价于 {1,} |
? | 匹配前面的表达式零个或一个 等价于 {0,1} |
{n} | 非负整数n,匹配确定的n次 |
{n,} | 前面的字符至少n次 |
{n,m} | n <= m 最少n次最多m次 |
* 和 + 都是贪婪匹配,他们会尽可能多的匹配文字。在后面加上一个? 即可实现非贪婪匹配。
<h1>RUNOOB-菜鸟教程</h1>
/<.*>/ // 会匹配整个字符串
/<.*?>/ // 只匹配 <h1>
通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从"贪婪"表达式转换为"非贪婪"表达式或者最小匹配。
定位符
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与 \n 或 \r 之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与 \n 或 \r 之前的位置匹配。 |
\b | 匹配一个单词边界,即字与空格间的位置。 |
\B | 非单词边界匹配。 |
捕获组
用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔。
匿名捕获组
() 表示捕获分组,() 会把每个分组里的匹配的值保存起来, 多个匹配值可以通过数字 n 来查看(n 是一个数字,表示第 n 个捕获组的内容)。同时捕获组还可以在替换的时候通过 $
符号引用,在正则表达式中使用 \1
的形式实现反向引用
例如:
'abcd1234'.replace(/cd([0-9]*)/,"fg($1)");
// 'abfg(1234)'
'abcd1234,1234'.replace(/cd([0-9]*),\1/,"fg($1)");
// 'abfg(1234)'
上面的操作把数字部分作为一个捕获组,给数字外面添加了一对括号。JS中匿名捕获组$支持1-99,依次匹配第1到第99个括号。
命名捕获组(ECMAScript 2018)
如下:
'abcd1234,1234'.replace(/cd(?<number>\d*)/,"fg($<number>)")
'abcd1234'
// 命名捕获组在的反向引用
'abcd1234mm1234'.replace(/cd(?<number>\d*)mm\k<number>/,"fg($<number>)")
?<xx>
: 命名;
\k<xx>
: 正则表达式中反向引用;
$<number>
: 替换字符串中反向引用;
命名的捕获组同时可以使用数字索引引用,命名捕获组的好处在于,如果修改了正则表达式不需要调整相关的引用的顺序。
\d === [0-9]
非捕获元
上文的圆括号会有一个副作用,使相关的匹配会被缓存,此时可用 ?:
放在第一个选项前来消除这种副作用。
比如/industr(?:y|ies)/
这个正则表达式中的括号的匹配结果并不需要存起来,就可以使用 ?:
来消除这种副作用。
正向预查
- 正向肯定预查:
?=
—> exp1(?=exp2) 查找以exp2结尾的字符exp1; - 正向否定预查:
?<=
----> exp1(?!exp2) 查找不是 exp2 结尾的 exp1。
反向预查
- 反向肯定预查
?<=
(?<=exp1)exp2 查找以exp1开头的 exp2。 - 反向否定预查
?<!
(?<!exp1)exp2 查找不是以 exp1 的 exp2。
反向引用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。
可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。
反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例:
Is is the cost of of gasoline going up up?
var str = "Is is the cost of of gasoline going up up";
var patt1 = /\b([a-z]+) \1\b/ig;
document.write(str.match(patt1));
// 移除script和style标签之间的所有内容
content.replace(/<(script|style)[\s\S]+<\/\1>/g, '').trim()