正则表达式的意外匹配

时间:2017-10-29 12:06:05

标签: r regex

我希望正则表达式模式ab{,2}c仅与a匹配,后跟0,1或2 b s,后跟c

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

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

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

  

{n,m}前面的项目至少匹配n次,但不是更多   比m次。

所以我同意将{,2}写成{0,2}作为有效模式(与Python不同,文档明确声明省略n指定零下限)。

但是然后使用{,2}会抛出错误而不是返回误导性的匹配!我错过了什么或者是否应该将其报告为错误?

3 个答案:

答案 0 :(得分:8)

不期望使用{,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

答案 1 :(得分:1)

只是一个补充:

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}$

答案 2 :(得分:-1)

我写这个作为答案,因为不幸的是我无法添加评论。

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

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

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

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