foo(\b)?
。这是一个实验,看看我是否可以通过检查第一组是否匹配(并导致空字符串)来推断边界的存在。
我用一些语言尝试过:PHP/Python/Java/C#/Rust手动输入。所有这些都按预期运行:第一个匹配为空字符串,第二个匹配为
null
/None
/无。
然而,JS 的情况并非如此,因为它在与
undefined
的两场比赛中都为第 1 组输出 foo food
。
console.config({ maximize: true });
console.log(...'foo food'.matchAll(/foo(\b)?/g));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
但是,没有
(\b)
的 ?
会捕获空字符串。
console.config({ maximize: true });
console.log(...'foo food'.matchAll(/foo(\b)/g));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
考虑到
?
是贪婪的,
(\b)
不应该像其他语言一样始终匹配并捕获第一个
foo
之后的空字符串吗?有哪些替代方案?我可以在 NodeJS 和 Chrome (V8) 以及 Firefox (Gecko) 中重现这一点,所以这可能是一个怪癖而不是一个错误。
正如问题和评论中所讨论的,这是一个怪癖。我不知道为什么也不知道如何,但我找到了替代方案:
foo(?:(\b)|)
。如果第一个分支匹配,则组 1 会产生空字符串,否则不会产生任何结果,从而有效地禁用
?
的这种奇怪行为。[...'foo food'.matchAll(/foo(?:(\b)|)/g)]
// [0: 'foo', 1: '']
// [0: 'foo', 1: undefined]
尝试一下:
console.config({ maximize: true });
console.log(...'foo food'.matchAll(/foo(?:(\b)|)/g));
<script src="https://gh-canon.github.io/stack-snippet-console/console.min.js"></script>
空分支最常被视为
?
、[需要引用]的不推荐版本,但似乎它们毕竟有一些差异,至少在 ECMAScript 中是这样。