正则表达式会被编译成 确定性有限自动机(DFA) 或 非确定性有限自动机(NFA),不同引擎实现不同。 JavaScript 使用 回溯型 NFA 引擎(特点:支持复杂语法,但可能效率低)。
示例:
const regex = /a+b/; // 编译为内部状态机"cab".match(/ab/); // 匹配成功:从索引1开始匹配 'ab'"aaab".match(/a+?b/); // 非贪婪匹配:'aaab'
"aaab".match(/a+b/); // 贪婪匹配:'aaab'?):尽可能少匹配
当路径匹配失败时,引擎回退到最近决策点尝试其他分支:
// 正则表达式:/.*abc/
const str = "xyzabc123abc";// 匹配过程:
1. .* 吞并整个字符串
2. 无法匹配 'abc' → 回溯到最后一个字符
3. 逐步释放字符,直到找到 'abc'.test() 方法深度解析const regex = /\d{3}/;
console.log(regex.test("abc123")); // trueg) 的影响const regex = /a/g;
const str = "abcabc";
console.log(regex.test(str)); // true (索引0)
console.log(regex.lastIndex); // 1
console.log(regex.test(str)); // true (索引3)
console.log(regex.lastIndex); // 4
console.log(regex.test(str)); // false
console.log(regex.lastIndex); // 0 (自动重置)lastIndex 属性 跟踪匹配位置
// 危险写法:嵌套量词
/(a+)+b/.test("aaaaaaaaac"); // 指数级回溯
// 优化方案:
/a+b/.test("aaaaaaaaac"); // 线性复杂度// 低效:每次创建新正则
function check(str) {
return /\d{5}/.test(str);
}
// 高效:复用编译好的正则
const zipRegex = /\d{5}/;
function checkOptimized(str) {
return zipRegex.test(str);
}// 未锚定:全字符串搜索
/^\d+$/.test("12345"); // 严格检查全数字
// 等效但更高效:
function isAllDigits(str) {
return /^\d+$/.test(str);
}.test() 与 .exec() 对比
const regex = /(\d{4})-(\d{2})/g;
const str = "2023-01 2024-02";
while ((match = regex.exec(str)) {
console.log(`Year: ${match[1]}, Month: ${match[2]}`);
}
// Output:
// Year: 2023, Month: 01
// Year: 2024, Month: 02const regex = /a/g;
// 第一次测试
console.log(regex.test("abc")); // true
// 第二次测试不同字符串
console.log(regex.test("aaa")); // false(因为 lastIndex=1)// 错误匹配 emoji
/^.$/.test("👽"); // false(普通 . 无法匹配代理对)
// 正确方式:
/^.$/u.test("👽"); // true(使用 unicode 标志).test():需要快速判断是否存在匹配时使用
/pattern/ 比 new RegExp 更高效
String.prototype.includes() 代替简单字符串检查