如果我看文档,它说*
应该总是贪婪的,但在这种情况下,它不是:
// returns 'password*****' instead of 'password: *****'
'password: "something"'.replace(/(?<=password[ :]*)[^n,]+/i, '*****')
来自 TC39 DOCS
lookbehind proposal
模式通常从最左边的子模式开始匹配,如果左侧子模式成功,则移动到右侧的子模式。当包含在后视断言中时,匹配顺序将颠倒。模式将从最右边的子模式开始匹配,然后向左前进。例如,给定/(?<=$d+.)d+/
,模式将首先找到一个数字,并首先确保它前面有 。向后,然后 \d+ 从 .,最后 $ 从断言中的 \d+ 开始。回溯方向也将因此而逆转。
由于您的[^n,]+
将匹配除new line and ,
之外的所有字符,因此它也将捕获:
,并且您的回溯将看不到它,因为它已经被一个又一个回头的断言捕获,
您可以做的是使用+
这将确保您至少匹配one space or :
'password: "something"'.replace(/(?<=password[ :]+)[^n,]+/i, '*****')
@CodeManiac的答案是正确的;但是,为了进一步改进您的正则表达式,您可能需要执行以下操作:
const regex = /(password[: ]+)([^n,]+)/i;
const passwordStr = 'password: something';
console.log(passwordStr.replace(regex, '$1***********'))
有了这个,基本上你正在创建 2 个匹配组:提示 (password:
( 和值 (something
(。 然后,将字符串替换为第一组 ($1
=password:
(,后跟星号。
在处理后视时,它首先在后视之后搜索模式,在本例中为[^n,]+
。然后,它测试后视是否与该位置左侧的字符串部分匹配;如果是这样,则匹配成功,否则重复,寻找主模式的下一个匹配。它不是从寻找回头开始的。
[^n,]+
匹配输入中的每个子字符串。当它到达子字符串<space>"something"
时,后视匹配,因为[ ;]*
匹配空字符串。它不会继续尝试进一步的匹配以使后视匹配成为更长的前缀。