首页 > 解决方案 > “最多”的正则表达式

问题描述

我目前正在考虑如何最好地将“最多两个”表示为正则表达式。

str_detect("xxx", "x{0,2}")给了TRUE,我明白为什么。例如因为前两个x。我想要一个给出FALSE. str_detect("xxx", "x{0,2}[^x]")达到这个,就好了。str_detect("xxx", "x{0,2}(?!x)")导致TRUE,因此我很惊讶。为什么会这样?

你能想到另一个比 更聪明的正则表达式x{0,2}[^x]吗?我认为没关系,但我想知道是否没有更短的解决方案。

标签: rregexstringr

解决方案


您应该准确地说“最多”的含义。您正在使用该表达式来表示 0、1 或 2 次出现,并且用{0,2} 限制量词表示。

但是,单个字符重复可以立即连续发生,也可以在两者之间的某个距离内发生。也就是说,重复可以是连续的和非连续的。在前一种情况下,我们x{0,2}在肯定语境或x{3}否定语境中使用,在后者中,我们必须使用排除字符的量化否定字符类,如(?:[^x]*x){0,2}(肯定语境)/ (?:[^x]*x){3}(否定语境)。

正面/负面的背景是什么?当您说“最多 2”时,它等于“不超过 3”。因此,如果匹配出现 N+1 次,则匹配应该失败。在大多数情况下,积极的上下文是用常规的消费上下文设置的,消极的上下文通常是在消极的环顾中设置的。

“至多”的例子

  • 一个字符串中最多出现 2 次连续 b字符:str_detect(c("aaa","abc","abb","bbb","babnbdb"), "^(?!.*b{3})")(=> [1] TRUE TRUE TRUE FALSE TRUE)
  • 一个单词中最多连续重复2 次: (=> )bstr_extract_all("aaa abc abb bbb babnbdb", "\\b(?!\\p{L}*b{3})\\p{L}+\\b")[1] "aaa" "abc" "abb" "babnbdb"
  • 在一个字符串中最多不连续重复2 次: (=> )bstr_detect(c("aaa","abc","abb","bbb","babnbdb"), "^(?:[^b]*b){0,2}[^b]*$")[1] TRUE TRUE TRUE FALSE FALSE
  • 在任何单词中最多不连续重复2 个b字母:str_extract_all("aaa abc abb bbb babnbdb", "\\b(?!(?:[\\p{L}--[b]]*b){3})\\p{L}+\\b")(=> [1] "aaa" "abc" "abb")

在线查看R 演示


推荐阅读