我正在测试使用交替进行回溯和匹配失败.
说我有以下正则表达式:
(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,但如果foo之后没有b则失败?意味着右侧表达甚至不会被看到或匹配.
所以在这种情况下,第三个字符串会完全失败,因为在fooquz中foo之后没有b因此它不应该尝试右侧表达式而整个匹配将无法返回根本没有结果?
解决方法
如果您不熟悉(
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,perl=T))) ## [[1]] ## [1] "foobar" "barbaz" ## [[2]] ## [1] "barbaz"
说明:
>(* COMMIT)导致整体失败,没有起点前进.>(* THEN)导致在回溯到达时跳到下一个最里面的替代.>如果foo匹配但b失败,则回溯到(* COMMIT)会导致整个匹配失败.>如果foo和b匹配,但是ar失败,则回溯到(* THEN)会导致尝试下一个替代barbaz.