正则表达式通常用来查找和替换字符串。

JavaScript 中,正则表达式使用 [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) 类的实例表示,它也被整合到了字符串方法中。

正则表达式

组成

正则表达式由两部分组成:模式(pattern) 和 修饰符(flags),修饰符是可选的。

  • 模式表示要匹配的内容
  • 修饰符表示以何种方式匹配

创建

JavaScript 中有两种创建正则表达式的方式。

一、构造函数语法

  1. regexp = new RegExp('pattren'); // 没有修饰符
  2. regexp = new RegExp('pattren', 'gmi'); // 有修饰符 g,m 和 i(之后会讲到)

二、字面量语法(双斜线语法)

  1. regexp = /pattern/; // 没有修饰符
  2. regexp = /pattern/gmi; // 有修饰符

通过上面两种方式创建的 regexp 都是内置 RegExp 类的实例。

注意:方便起见,后面我都会用“RegExp 对象”来做表述,它与“RegExp 类的实例”是一个意思。

上面两种语法的区别在于:

  1. 字面量语法是静态的,不支持动态插入表达式。使用这种方式创建 RegExp 对象时,正则规则是已知的
  2. 使用 RegExp 构造函数创建的对象,是支持动态插入表达式的。比如:通过模板字符串的插值语法 ${...}
  1. let tag = prompt("What tag do you want to find?", "h2");
  2. let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above

修饰符

下面列举了可以在正则表达式上应用的修饰符:

修饰符 作用
i 加上即表示匹配时忽略大小写。比如:Aa 会被当做相同字符
g 执行全局匹配。默认只返回第一个匹配项
m 多行匹配。
s 启用“dotall”模式,即点符号(.)还能匹配换行符 \\n
u 启用“Unicode 模式”模式,能正确处理大于 \\uFFFF 的 Unicode 字符
y 启用“粘性”模式,在文本中的某个确切位置进行查找

JavaScript 中常用修饰符有三个:igu

现在不需要立即搞懂所有这些修饰符的意思,因为后续都会讲到。

应用

开篇有提到,正则表达式有被整合到字符串方法中,下面列举两个常用方法来说明。

查找:str.match(regexp)

str.match(regexp) 方法查找 str 中所有与 regexp 匹配的项目,返回结果一共有三种情况:

没有匹配项就返回 null

  1. "JavaScript".match(/HTML/);
  2. //=> null

有匹配项、而且是全局匹配

这种情况,会返回由所有匹配项组成的数组。

  1. "We will, we will rock you".match(/we/ig);
  2. //=> ["We", "we"]

有匹配项、但不是全局匹配

这种情况,返回结果看起来有点多,先来直观感受下:

  1. "We will, we will rock you".match(/we/i);
  2. //=> ["We", index: 0, input: "We will, we will rock you", groups: undefined]

返回的也是一个数组。数组的第一个元素是整个正则表达式匹配的内容,后续元素有无,取决于正则表达式中是否包含捕获组。

当正则表达式中包含捕获组时,从数组第二个元素开始,分别对应每个捕获组匹配的内容,元素顺序取决于正则表达式中捕获组的顺序。

提示:捕获组后续会讲到,现在不懂也没关系

除此之外,数组上会多出三个属性:indexinputgroups

  • index 表示匹配内容在字符串中的起始索引位置
  • input 表示用来做匹配的原始字符串
  • groups 是一个映射对象,由命名捕获组组名和匹配内容组成。如果正则表达式中没有命名捕获组,那么这个属性值就为 undefined

替换:str.replace(regexp, replacement)

这里的 replacement 是一个字符串,用来替换掉字符串 str 中与 regexp 匹配的内容。默认只替换第一个匹配项,使用修饰符 g 就能替换所有匹配项。

  1. // 不带修饰符 g,只会替换第一个 We
  2. alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
  3. // 带修饰符 g,两个 We 都会被替换
  4. alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will

replacement 中还支持使用一些特殊符号(使用美元符 $ 开头),用来引用部分正则表达式的匹配内容。

特殊符号 含义
$& 代表完整匹配内容(whole match)
`$`` 代表匹配内容之前的字符串部分
$' 代表匹配内容之后的字符串部分
$n n 是一个 1~2 位的数值,代表第 n 个捕获组的匹配内容
$<name> 代表命名捕获组 name 的匹配内容
$$ 插入字符 $

$& 为例:

  1. alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript

判断:regexp.test(str)

讲完了字符串中跟正则相关的方法,下面就来讲正则对象上支持的一个方法:regexp.test(str)。这个方法用来判断字符串 str 中是否有内容与正则表达式的规则匹配。如果有的话返回 true,否则返回 flase

  1. let str = "I love JavaScript";
  2. let regexp = /LOVE/i;
  3. alert( regexp.test(str) ); // true

本章只是正则表达式相关内容的简单入门,关于字符串和 RegExp 方法的完整信息,请查阅《RegExp 和字符串上的方法》一章内容。

总结

  • 正则表达式由两部分组成:模式(pattern) 和 修饰符(flags)。
  • 如果正则表达式没有使用修饰符和特殊符号,那么它其实等同于在查找子串。
  • str.match(regexp) 方法用来查找字符串中与指定正则规则相匹配的内容。默认只匹配第一项,加了修饰符 g 之后匹配所有项。
  • str.replace(regexp, replacement) 方法使用 replacement 来替换 str 中与 regexp 匹配的内容:默认只替换匹配到的第一项,加了修饰符 g 之后,会替换所有匹配项。
  • 只要 str 中有一个匹配项,regexp.test(str) 方法就返回 true,否则返回 false

📄 文档信息

🕘 更新时间:2021/08/20
🔗 原文链接:https://javascript.info/regexp-introduction