具有多字符 unicode 符号的正则表达式匹配行为

Regex matching behavior with multi-character unicode symbol

我无法理解使用多字符 unicode 符号观察到的一些行为。

以字符串 </code> 和正则表达式 <code>(|)(?![]) 为例,我得到三个匹配项:两个标志和最后一手牌。 预期: 5 场比赛,每个符号一次。

因为 和 都是2个字符符号,我试着写了一个非unicode的例子。使用字符串 abcdabcdab 和正则表达式 (ab|cd)(?![b]),我得到了预期的 5 个匹配项,每对 abcd 一次。

考虑到 </code> 和 <code> 之间可能存在一些相互作用,我使用了不同的 unicode 字符,给了我正则表达式 (|)(?![]).在这里,我得到了与第一个示例中相同的结果。

由于 </code> 和 <code> 通常不单独使用,我尝试使用“普通”unicode 或 ASCII 字符而不是 </code>。在我的示例中,我使用了 <code>a,这给了我 5 场比赛的预期结果,每个符号一次。

是否有人能够解释这种行为,或者这是一个错误?

此行为仅发生在 PCRE 和 JavaScript 正则表达式引擎中,我使用此站点对其进行了测试。 https://regex101.com/

您不应像 (?![]) 那样将多字节字符放入字符 class 中。在字符 class 内,它被“分解”为两个字节的序列, \uD83C\uDFFE ,匹配其中任何一个,而不是作为序列。由于手表情符号是 \uD83E\uDD1A\uD83C\uDFFE 的序列(以这两个字节结尾),因此触发了前瞻并影响了匹配。

要解决这个问题,你只需要去掉括号并使用(|)(?!),这样 char就可以被当作一个字节序列,不是一个或另一个字符。