【问题标题】:Regex matching behavior with multi-character unicode symbol具有多字符 unicode 符号的正则表达式匹配行为
【发布时间】:2021-07-29 10:10:35
【问题描述】:

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

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

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

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

由于???????? 通常不单独使用,我尝试使用“普通”Unicode 或ASCII 字符代替????。在我的示例中,我使用了 ????a,这给了我 5 次匹配的预期结果,每个符号一次。

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

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

【问题讨论】:

  • 您不应该在字符类中放置多字节字符,您只需删除括号(????????|????????)(?!????)。在字符类内部,它被“分解”为两个字节的序列,\uD83C\uDFFE 匹配其中任何一个,而不是作为序列,而手形表情符号是\uD83E\uDD1A\uD83C\uDFFE 的序列(以这两个字节结尾)

标签: regex unicode pcre


【解决方案1】:

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

要解决此问题,您只需删除括号并使用(??|??)(?!?) 以便? 字符可以被视为字节序列,而不是一个或另一个字符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-16
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多