Regex 引擎在内部是如何工作的

A 遍历主题字符串,在前进到字符串中的下一个字符之前尝试正则表达式的 所有排列

文本导向的引擎永远 不会回溯

一个 B 遍历 regexp,尝试将 regexp 中的下一个标记与下一个字符匹配。

如果找到匹配项,引擎将通过 regexp 和主题字符串前进。

如果无法匹配,引擎将 回溯regexp 和主题字符串中的先前位置,在该位置它可以尝试通过正则表达式的不同路径。

总是返回最左边的匹配

理解这一点 非常重要

正则表达式引擎总是返回最左边的匹配,即使稍后可以找到“更好”的匹配。

将正则表达式应用于字符串时,引擎从字符串的第一个字符开始。

它在第一个字符处尝试正则表达式的所有可能排列。

只有在尝试了所有可能性并发现失败时,引擎才会继续处理文本中的第二个字符。

同样,它以完全相同的顺序尝试所有可能的正则表达式排列。

结果是正则表达式引擎返回 最左边 的匹配。

进阶语法

命名捕获: ?<name>

'<div>hello 123<\\/div>'.replace(/(?<text>\\d+)/, '<em>$<text></em>')

非捕获模式: ?:

var str = 'scq000'.
str.replace(/(scq00)(?:0)/, '$1,$2')
// 返回scq00,$2
// 由于使用了非捕获正则,所以第二个引用没有值,这里直接替换为$2

前向查找: ?=?!

// 前向查找:?=
'happy happily'.match(/happ(?=ily)/)
// 匹配到了 happ 开头且 ily 结尾的 happily

// 负前向查找:?!
'happy happily'.match(/happ(?!ily)/)
// 匹配到了开头 happ 且非 ily 结尾的 happy

向查找: ?<= ?<!

// 后向查找
'apple people'.match(/(?<=ap)ple/)
// 匹配到了 ple 结尾且前面是 ap 的 apple

// 非后向查找
'apple people'.match(/(?<!ap)ple/)
// 匹配到了 ple 结尾且前面不是 ap 的 people

例子