如果条件不满足,则使整个匹配失败

时间:2014-08-17 17:34:38

标签: regex r

我正在测试使用交替进行回溯和匹配失败。

说我有以下正则表达式:

(foobar|barbaz)

我在以下字符串的向量上运行它。

x <- c('In context I have foobar and barbaz', 'In context I have foobaz and barbaz', 'In context I have fooquz and barbaz')
regmatches(x, gregexpr('(foobar|barbaz)', x))
# [[1]]
# [1] "foobar" "barbaz"

# [[2]]
# [1] "barbaz"

# [[3]]
# [1] "barbaz"

有没有办法让比赛完全失败,没有结果?

例如,在正则表达式(foobar|barbaz)中有一种方法可以使整个匹配完全失败,如果左侧表达式仅匹配到foo,但如果没有b则失败在foo之后?这意味着右侧表达甚至不会被看到或匹配。

因此,在这种情况下,第三个字符串将完全失败,因为b中的foo之后没有fooquz因此它不应该尝试右侧表达式并且整个匹配将无法返回根本没有结果?

2 个答案:

答案 0 :(得分:6)

如果您不熟悉(PCRE),那么在推进之前阅读文档将使您受益。您可以使用perl = TRUE启用PCRE并使用回溯动词。

> x <- c('foobar and barbaz', 'foobaz and barbaz', 'fooquz and barbaz')
> regmatches(x, gregexpr('(foo(*COMMIT)b(*THEN)ar|barbaz)', x, perl=T))
## [[1]]
## [1] "foobar" "barbaz"

## [[2]]
## [1] "barbaz"

## [[3]]
## character(0)

要清楚地看到第三个向量元素完全失败,请过滤结果。

> Filter(length, 
         regmatches(x, gregexpr('(foo(*COMMIT)b(*THEN)ar|barbaz)', x, perl=T)))
## [[1]]
## [1] "foobar" "barbaz"

## [[2]]
## [1] "barbaz"

<强>解释

  • (*COMMIT)导致整体失败,没有提升起点。
  • (*THEN)会在回溯到达时跳转到下一个最里面的替代方案。

  • 如果foo匹配,但b失败,则回溯到(*COMMIT)会导致整个匹配失败。

  • 如果foob匹配,但ar失败,则(*THEN)的回溯会导致尝试下一个替代barbaz。< / p>

答案 1 :(得分:0)

是的,你可以使用(*COMMIT)回溯控制动词:

(?:foo(*COMMIT)bar|barbaz)

如果模式失败后,此动词将导致整个模式失败。