我正在测试使用交替进行回溯和匹配失败。
说我有以下正则表达式:
(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
因此它不应该尝试右侧表达式并且整个匹配将无法返回根本没有结果?
答案 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)
会导致整个匹配失败。
如果foo
和b
匹配,但ar
失败,则(*THEN)
的回溯会导致尝试下一个替代barbaz
。< / p>
答案 1 :(得分:0)
是的,你可以使用(*COMMIT)
回溯控制动词:
(?:foo(*COMMIT)bar|barbaz)
如果模式失败后,此动词将导致整个模式失败。