JS regex positive look behind * 应该什么时候不贪心?

JS regex positive look behind * not greedy when it should?

如果我查看文档,它说 * 应该总是贪婪的,但在这种情况下它不是:

// returns 'password*****' instead of 'password: *****'
'password: "something"'.replace(/(?<=password[ :]*)[^\n,]+/i, '*****') 

FROM TC39 DOCS lookbehind proposal

模式通常从最左边的子模式开始匹配,如果左边的子模式成功,则继续匹配右边的子模式。当包含在回顾断言中时,匹配的顺序将被颠倒。模式将从最右边的子模式开始匹配,然后向左推进。例如,给定 /(?<=$\d+\.)\d+/,该模式将首先找到一个数字并首先确保它前面有 。向后移动,然后是 \d+ 从 . 开始,最后 $ 从断言中的 \d+ 开始。回溯方向也会因此反转。


因为你的 [^\n,]+ 将匹配除 new line and , 之外的所有字符,所以它也会捕获 : 并且你的后视不会看到它,因为它已经被后视后的断言捕获,

你可以做的是使用 + 这将确保你至少匹配 one space or :

'password: "something"'.replace(/(?<=password[ :]+)[^\n,]+/i, '*****') 

处理回溯时,它首先搜索回溯之后的模式,在本例中为 [^\n,]+。然后它测试lookbehind是否与该位置左侧的字符串部分匹配;如果匹配则匹配成功,否则重复,寻找主模式的下一个匹配。它不是从搜索后视开始的。

[^\n,]+ 匹配您输入的每个子字符串。当它到达子字符串 <space>"something" 时,lookbehind 匹配,因为 [ ;]* 匹配一个空字符串。它不会继续尝试进一步匹配以使后向匹配具有更长的前缀。

@CodeManiac 的回答是正确的;但是,要进一步改进您的正则表达式,您可能需要这样做:

const regex = /(password[: ]+)([^\n,]+)/i;
const passwordStr = 'password: something';

console.log(passwordStr.replace(regex, '***********'))

有了这个,您基本上创建了 2 个匹配组:提示 (password:) 和值 (something)。然后将字符串替换为第一组 (</code> = <code>password:),后跟星号。