【问题标题】:Unexpected match of regex正则表达式的意外匹配
【发布时间】:2017-10-29 12:06:05
【问题描述】:

我希望正则表达式模式 ab{,2}c 仅匹配 a 后跟 0、1 或 2 bs,然后是 c

它在许多语言中都以这种方式工作,例如 Python。但是,在 R 中:

grepl("ab{,2}c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
# [1]  TRUE  TRUE  TRUE  TRUE FALSE

我对第四个TRUE 感到惊讶。在?regex,我可以阅读:

{n,m} 前一项至少匹配n 次,但不会更多 比m 次。

所以我同意 {,2} 应该写成 {0,2} 是一个有效的模式(不像在 Python 中,文档明确指出省略 n 指定下限为零)。

但是使用{,2} 应该会抛出错误,而不是返回误导性匹配!我是否遗漏了什么,还是应该将其报告为错误?

【问题讨论】:

  • 您使用了默认的 TRE 正则表达式引擎。如果您使用 PCRE 之一,您将得到所有项目的错误。始终指定下限以获得跨引擎的一致行为。
  • 这太疯狂了!对我来说似乎是一个错误。
  • @Wiktor:我关心的是 TRE 引擎本身的一致性:当我要求它最多匹配 2 bs?

标签: r regex


【解决方案1】:

{,2} 的行为不是预期的,这是一个错误。如果您查看 TRE 源代码 tre_parse_bound method,您将看到在引擎尝试初始化最小界限之前,min 变量值设置为 -1。在量词中缺少最小值的情况下,“重复”的数量似乎是最大值的数量+1(好像重复数等于max - min = max - (-1) = max+1)。

所以,a{,} 匹配一次出现的a。与a{, }a{ , } 相同。见R demo,只有abcab{,}c匹配:

grepl("ab{,}c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
grepl("ab{, }c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
grepl("ab{ ,   }c", c("ac", "abc", "abbc", "abbbc", "abbbbc"))
## => [1] FALSE  TRUE FALSE FALSE FALSE

【讨论】:

【解决方案2】:

作为补充:

vec1 = c('','a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa','aaaaaaa')

grep("^a{,1}$", vec1, value = T) # seems to "become" ^a{1}$
grep("^a{,2}$", vec1, value = T) # seems to "become" ^a{0,3}$
grep("^a{,3}$", vec1, value = T) # seems to "become" ^a{0,4}$
grep("^a{,4}$", vec1, value = T) # seems to "become" ^a{0,5}$

【讨论】:

    【解决方案3】:

    我正在写这个作为答案,因为很遗憾我无法添加评论。

    更新:根据 Wiktor Stribiżew 的回答和反馈,该行为似乎是一个错误的类别。

    原始:您使用的语法在 R 中不受支持(假设为默认引擎)。这就是为什么你会得到意想不到的结果。

    • 如文档所述,支持的语法为 {n,m}。因此,您需要指定两个边界,例如{0,2},这将返回正确的结果。
    • 另一方面,正则表达式文档中缺少语法 {,m},这表明它不受支持。

    如果您想探索语法差异,我建议您查看regular-expressions.info 比较页面。 (在这种情况下,您需要根据量词比较 Python 和 R。)

    【讨论】:

    • 感谢您的帮助,但正如我在上面的评论中所说,我主要关心的不是引擎之间缺乏一致性。我同意使用{0,2} 会产生正确的结果,但我的观点是{,2} 应该抛出错误(“无效的正则表达式”)或返回一致的匹配。
    • 如果不支持,它必须报错,而不是静默输出错误结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 2020-09-12
    相关资源
    最近更新 更多