Skip to content

ES6 - RegExp 对象

正则表达式(通常缩写为 “regex” 或 “regexp”)是定义搜索模式的字符序列。这些模式被字符串搜索算法用于对字符串进行“查找”或“查找和替换”操作,或用于输入验证。

在 JavaScript 中,正则表达式也是对象,由 RegExp 类表示。String 原型和 RegExp 原型都定义了利用正则表达式进行强大的模式匹配和文本操作的方法。

有两种方法可以创建 RegExp 对象:

// 1. 使用正则表达式字面量(当模式是常量时首选):
const patternLiteral = /abc/i; // 匹配 'abc', 'Abc', 'aBc' 等,不区分大小写。
// 2. 使用 RegExp 构造函数(当模式是动态的时很有用,例如来自用户输入):
const dynamicPattern = 'hello';
const flags = 'g'; // 全局匹配
const patternConstructor = new RegExp(dynamicPattern, flags); // 全局匹配 'hello'。
// 注意:当使用构造函数和字符串模式时,反斜杠需要进行转义。
// 例如,要匹配字面量反斜杠:new RegExp('\\') 对应于 /\/。

标志修改正则表达式搜索的行为。它们附加在字面量结束斜杠之后,或作为第二个参数传递给 RegExp 构造函数。

标志名称描述
g全局匹配查找所有匹配项而不是在找到第一个匹配项后停止。
i忽略大小写使匹配不区分大小写。
m多行将开头 (^) 和结尾 ($) 字符视为作用于多行(即匹配每行的开头或结尾,以 \n 或 \r 分隔),而不仅仅是整个输入字符串的开头或结尾。
uUnicode (ES6)将模式视为 Unicode 代码点序列。启用诸如使用 . 正确匹配星体符号(例如 emoji)和使用 Unicode 属性转义(例如 \p{Script=Greek})等功能。
y粘性 (ES6)仅从正则表达式在目标字符串中的 lastIndex 属性指示的索引处开始匹配。不会尝试从任何后续索引开始匹配。
s点匹配所有 / 单行 (ES2018)允许点 (.) 元字符匹配换行符(\n、\r 等)。没有 s 标志时,. 匹配除换行符外的任何字符。

方括号用于定义要匹配的字符集。

表达式描述
[abc]匹配任意一个字符:‘a’、‘b’ 或 ‘c’。
[^abc]否定集合:匹配不是 ‘a’、‘b’ 或 ‘c’ 的任意一个字符。
[0-9]范围:匹配从 0 到 9 的任意一个数字。
[a-z]范围:匹配从 ‘a’ 到 ‘z’ 的任意一个小写字母。
[A-Z]范围:匹配从 ‘A’ 到 ‘Z’ 的任意一个大写字母。
[a-zA-Z0-9_]常用于匹配字母、数字或下划线。等同于 \w。

量词指定字符、分组或字符类必须在输入中出现多少次才能找到匹配项。

量词描述
x*匹配 ‘x’ 零次或多次。
x+匹配 ‘x’ 一次或多次。
x?匹配 ‘x’ 零次或一次(可选)。
x{n}精确匹配 ‘x’ n 次。
x{n,}至少匹配 ‘x’ n 次。
x{n,m}匹配 ‘x’ 至少 n 次但不超过 m 次。
*?, +?, ??, {n,}?, {n,m}?惰性量词:匹配尽可能少的字符(非贪婪),与默认的尽可能多匹配的贪婪行为相对。
锚点描述
^匹配字符串的开头(或行的开头,如果使用了 m 标志)。
$匹配字符串的结尾(或行的结尾,如果使用了 m 标志)。
\b单词边界:匹配单词字符(\w)与非单词字符(\W)之间或字符串开头/结尾的位置。
\B非单词边界。

圆括号将正则表达式的一部分进行分组并创建捕获组。匹配的子字符串可以被记住并在以后访问。

  • (pattern):捕获组。匹配 pattern 并捕获匹配项。
  • (?:pattern):非捕获组。匹配 pattern 但不捕获匹配项。
  • (?<name>pattern):命名捕获组 (ES2018)。捕获匹配项并将其分配给 groups.name。

这些字符在正则表达式中具有特殊含义。要匹配它们的字面量,通常需要使用反斜杠 (\) 进行转义。

字符描述
.匹配除换行符外的任何单个字符(除非使用 s 标志)。
\d匹配任意数字。等同于 [0-9]。
\D匹配任意非数字字符。等同于 [^0-9]。
\w匹配任意单词字符(字母、数字 + 下划线)。等同于 [A-Za-z0-9_]。
\W匹配任意非单词字符。等同于 [^A-Za-z0-9_]。
\s匹配任意空白字符(空格、制表符、换行符等)。
\S匹配任意非空白字符。
\t匹配制表符。
\n匹配换行符。
\r匹配回车符。
\uxxxx匹配由十六进制数 xxxx 指定的 Unicode 字符。
\p{...}, \P{...}Unicode 属性转义(需要 u 标志,例如 \p{Script=Latn})。

|(或)运算符允许匹配多个表达式中的一个。例如,/cat|dog/ 匹配 ‘cat’ 或 ‘dog’。

属性描述
RegExp.prototype.flags (ES6)一个字符串,包含 RegExp 对象的标志(例如,“giu”)。
RegExp.prototype.global布尔值:是否设置了 g 标志。
RegExp.prototype.ignoreCase布尔值:是否设置了 i 标志。
RegExp.prototype.multiline布尔值:是否设置了 m 标志。
RegExp.prototype.unicode (ES6)布尔值:是否设置了 u 标志。
RegExp.prototype.sticky (ES6)布尔值:是否设置了 y 标志。
RegExp.prototype.dotAll (ES2018)布尔值:是否设置了 s 标志。
RegExp.prototype.source模式的文本(不包含标志)。
RegExp.prototype.lastIndex一个整数属性,指定下一次匹配开始的索引。与设置了 g 或 y 标志的 exec() 和 test() 一起使用。
  • RegExp.prototype.test(str):执行搜索,查找正则表达式与指定字符串之间的匹配项。如果找到匹配项,返回 true;否则返回 false。
  • RegExp.prototype.exec(str):在指定字符串中执行搜索。返回一个包含匹配信息的数组(如果没有匹配项,则返回 null)。如果设置了全局标志 (g),exec() 会更新 lastIndex,并且可以重复调用以查找所有匹配项。
  • String.prototype.match(regexp):检索字符串与正则表达式匹配的结果。如果 regexp 带有 g 标志,则返回所有匹配项的数组或 null。如果没有 g 标志,则返回与 regexp.exec(string) 相同的结果。
  • String.prototype.matchAll(regexp) (ES2020):返回一个迭代器,包含字符串与正则表达式匹配的所有结果,包括捕获组。要求 regexp 带有 g 标志。
  • String.prototype.replace(regexp|substr, newSubstr|function):返回一个新字符串,其中模式的部分或全部匹配项被替换。regexp 可以是字符串或 RegExp 对象。替换项可以是字符串(带有特殊替换模式,如 $&、$1)或函数。
  • String.prototype.search(regexp):执行搜索,查找正则表达式与此 String 对象之间的匹配项。返回第一个匹配项的索引,如果未找到匹配项,则返回 -1。忽略 g 标志。
  • String.prototype.split(separator|regexp[, limit]):使用指定的separator字符串或正则表达式,将一个 String 对象分割成字符串数组。
const text = 'The quick brown fox jumps over the lazy dog. The dog barks.';
// 测试是否存在 'fox'(不区分大小写)
const hasFox = /fox/i.test(text);
console.log('Has fox?', hasFox); // true
// 执行并查找第一个 'The'
const firstTheRegex = /The/;
const firstTheMatch = firstTheRegex.exec(text);
console.log('First \'The\' match:', firstTheMatch);
// 输出: [ 'The', index: 0, input: '...', groups: undefined ]
// 查找所有出现的 'The' 或 'the'
const allTheRegex = /the/gi;
let match;
const allMatches = [];
while ((match = allTheRegex.exec(text)) !== null) {
allMatches.push(match[0] + ' at index ' + match.index);
}
console.log('All \'the\' (global, case-insensitive):', allMatches);
// 输出: [ 'The at index 0', 'the at index 31', 'The at index 44', 'the at index 48' ]
// 使用 String.match()
const animals = text.match(/fox|dog/g); // 全局搜索 'fox' 或 'dog'
console.log('Animals found:', animals); // [ 'fox', 'dog', 'dog' ]
// 使用 String.replace()
const newText = text.replace(/dog/g, 'cat');
console.log('Replaced text:', newText);
// 输出: The quick brown fox jumps over the lazy cat. The cat barks.
// 使用 String.split()
const sentences = 'Hello. How are you? Fine, thanks.';
const parts = sentences.split(/[.?]/); // 按句号或问号分割
console.log('Split parts:', parts.filter(s => s.trim() !== '')); // 过滤掉尾部分隔符产生的空字符串
// 输出: [ 'Hello', ' How are you', ' Fine, thanks' ]

正则表达式是文本处理的强大工具。掌握它们可以显著简化许多编程任务。像 MDN Web Docs 等在线 [regex] 测试器和资源对于学习和实验非常有价值。