RegExp
[TOC]
索引
构造方法:
- new RegExp():
(pattern, flags?)
,用于动态创建正则表达式对象的构造函数,适用于模式需要运行时拼接的场景。
方法:
RegExp
构造方法
new RegExp()@
new RegExp():(pattern, flags?)
,用于动态创建正则表达式对象的构造函数,适用于模式需要运行时拼接的场景。
pattern:
string
,文本模式定义正则表达式的匹配规则。flags?:
g|i|m|s|u|y
,修饰符,控制正则表达式的匹配行为。g
:全局匹配。i
:忽略大小写。m
:多行匹配。s
:允许.
匹配换行符。u
:使用 unicode 码的模式进行匹配。y
:执行“粘性 (sticky
)”搜索,匹配从目标字符串的当前位置开始。
返回:
re:
RegExp
,返回包含模式和修饰符的正则表达式对象。
基本示例:
基础用法:
js// 匹配所有数字(全局+忽略大小写) const regex = new RegExp("\\d", "gi"); console.log("A1B2C3".match(regex)); // ["1", "2", "3"]
注意事项:
转义规则:字符串中的
\
需写为\\
,因为字符串本身会解释一次转义:js// 匹配数字 \d → 需写成 "\\d" const digitPattern = new RegExp("\\d+"); // 等价于 /\d+/ // 匹配点号(.)→ 需写成 "\\." const dotPattern = new RegExp("\\."); // 等价于 /\./
性能考虑:
- 避免在循环中重复创建相同的
RegExp
对象(建议提前创建)。 - 静态模式优先使用字面量
/.../
(加载时编译,效率更高)。
- 避免在循环中重复创建相同的
标志覆盖:当第一个参数是正则对象时,提供
flags
会覆盖原标志:jsconst re = new RegExp(/abc/g, "i"); console.log(re.flags); // "i"(覆盖了 g)
空匹配陷阱:空字符串
new RegExp("")
会匹配任何输入:jsconsole.log(new RegExp("").test("abc")); // true
进阶示例:
动态构建正则表达式:
jsconst userInput = "hello"; const dynamicRegex = new RegExp(`\\b${userInput}\\b`, "i"); // /\bhello\b/i console.log(dynamicRegex.test("Hello world")); // true
复制正则表达式:
jsconst original = /abc/g; const copy = new RegExp(original); // 复制模式 const withNewFlags = new RegExp(original, "i"); // 覆盖标志为 i
方法
exec()@
re.exec():(str)
,用于执行正则匹配并返回详细匹配信息。
str:
string
,要搜索的目标字符串。返回:
result:
array|null
,返回包含匹配结果的数组(匹配成功)或null
(匹配失败)。
基本示例:
基础匹配:
jsconst phoneRe = /(\d{3})-(\d{4})/; const result = phoneRe.exec('Tel: 123-4567'); console.log(result[0]); // "123-4567" console.log(result[1]); // "123" console.log(result[2]); // "4567" console.log(result.index); // 5
核心特性:
匹配成功时的返回数组结构:
js[ '匹配的完整文本', // 索引 0 '捕获组1内容', // 索引 1(如果有捕获组) '捕获组2内容', // 索引 2 ..., index: 匹配起始位置, // 数值属性 input: '原始输入字符串', // 字符串属性 groups: { // 对象属性(命名捕获组) '组名': '值', ... } ]
执行机制详解:
无全局标志 (
g
) 时:- 始终返回第一个匹配结果
- 忽略
lastIndex
属性
jsconst re = /a(b)/; const result = re.exec('abc abc'); // [ // 'ab', // 'b', // index: 0, // input: 'abc abc', // groups: undefined // ]
有全局标志 (
g
) 时:- 维护
lastIndex
属性(记录下次匹配起始位置) - 连续调用可遍历所有匹配
jsconst re = /a(b)/g; let result; while ((result = re.exec('abc abc')) !== null) { console.log(`在位置 ${result.index} 找到: ${result[0]}`); } // 在位置 0 找到: ab // 在位置 4 找到: ab
- 维护
粘滞模式 (
y
) 时:- 强制从
lastIndex
开始匹配 - 匹配失败时重置
lastIndex
为 0
jsconst re = /^a/y; re.lastIndex = 1; // 从索引 1 开始匹配 console.log(re.exec('baa')); // null(索引1位置是 'a',但要求开头必须是 'a') console.log(re.lastIndex); // 0(匹配失败时自动重置为0)
- 强制从
注意事项:
全局匹配状态:
使用
g
标志时,正则对象会维护lastIndex
属性,不要复用同一个正则对象执行不同字符串的全局匹配:jsconst re = /a/g; re.exec('abc'); // 匹配成功 re.exec('axyz'); // 从 lastIndex=1 开始匹配 'xyz' → 失败
性能优化:
避免在循环中重复创建正则对象:
js// 错误做法(每次循环都创建新正则) for (let i=0; i<1000; i++) { /a/g.exec(str); } // 正确做法(提前创建) const re = /a/g; for (let i=0; i<1000; i++) { re.lastIndex = 0; // 重置指针 re.exec(str); }
进阶示例:
命名捕获组:
jsconst re = /(?<year>\d{4})-(?<month>\d{2})/; const result = re.exec('2023-10'); console.log(result.groups.year); // "2023" console.log(result.groups.month); // "10"
空匹配:
jsconst re = /a*/; console.log(re.exec('b')); // [ '', index: 0, input: 'b', groups: undefined ]
多行匹配:
jsconst re = /^a/m; // 多行模式 const result = re.exec('b\na'); console.log(result.index); // 2(匹配到第二行开头的 'a')
test()@
re.test():(str)
,用于快速检测字符串中是否存在匹配模式。
str:
string
,被测试匹配的字符串。返回:
isMatched:
boolean
,返回符串中是否存在至少一个匹配项。
基本示例:
简单验证:
js// 验证字符串是否包含数字 const hasDigit = /\d/; console.log(hasDigit.test("Hello123")); // true console.log(hasDigit.test("Hello")); // false
核心特性:
执行机制详解:
无全局标志 (
g
) 时:- 始终检测第一个匹配
- 不修改正则对象的
lastIndex
属性 - 多次调用结果相同
jsconst re = /a/; console.log(re.test("abc")); // true console.log(re.test("abc")); // true(结果不变) console.log(re.lastIndex); // 0(未被修改)
有全局标志 (
g
) 时:- 维护
lastIndex
属性(记录下次匹配起始位置) - 连续调用可遍历所有匹配
jsconst re = /a/g; const str = "aba"; console.log(re.test(str)); // true(位置0) console.log(re.lastIndex); // 1 console.log(re.test(str)); // true(位置2) console.log(re.lastIndex); // 3 console.log(re.test(str)); // false(无更多匹配) console.log(re.lastIndex); // 0(自动重置)
- 维护
粘滞模式 (
y
) 时:- 强制从
lastIndex
精确位置开始匹配 - 匹配失败则重置
lastIndex
为 0
jsconst re = /a/y; re.lastIndex = 1; console.log(re.test("baa")); // true(索引1匹配) console.log(re.lastIndex); // 2 re.lastIndex = 3; console.log(re.test("baa")); // false(超出范围) console.log(re.lastIndex); // 0(自动重置)
- 强制从
进阶示例:
粘滞模式精确匹配:
js// 检测连续出现的数字 const re = /\d+/y; re.lastIndex = 4; // 从索引4开始 console.log(re.test("123abc456")); // false(索引4是字母b) console.log(re.test("123 456")); // true(索引4是空格后的4)
空匹配:空模式始终返回 true(包括空字符串)
js// 空模式始终返回 true(包括空字符串) console.log(RegExp("").test("abc")); // true console.log(RegExp("").test("")); // true
多行匹配:
js// 检测每行是否以数字开头 const re = /^\d/m; console.log(re.test("1st line\n2nd line")); // true console.log(re.test("abc\n123")); // true(第二行匹配)