理解R regexp中的先行

时间:2017-01-23 08:52:19

标签: r regex

我尝试使用多个前瞻来模拟带有grep的R Perl类型正则表达式中的AND运算符。但是,我不理解我所看到的输出。这是一个示例代码块

a <- c("abcxyz", "abcdef", "defxyz", "abcdefxyz", "xyzdefabc")
grep("(?<=abc)(?=xyz)", a, ignore.case=TRUE, perl=TRUE)  # returns 1
grep("(?=abc)(?=xyz)", a, ignore.case=TRUE, perl=TRUE)  # returns integer(0)

第二行表明字符串中的位置在abc和xyz之间,并匹配&#39; abcxyz&#39;。为什么它不匹配&#39; abcdefxyz&#39;?

在第三行,我试图输出1,4和5,但它返回未找到。为什么会这样?

我正在使用下面的替代解决方案,但我想在处理多个前瞻时使用前瞻来处理排序。

grep("abc.*xyz|xyz.*abc", a, ignore.case=TRUE, perl=TRUE)  # returns 1 4 5 as expected

1 个答案:

答案 0 :(得分:7)

(?<=abc)(?=xyz)正则表达式仅匹配abcxyz之间的位置(字符串中的位置)。它会在abcxyz中找到匹配项,但在abcdefxyz中找不到匹配项,因为xyz不会立即跟随abc

(?=abc)(?=xyz)模式永远不会匹配任何内容,因为它匹配字符串中的位置,后面跟一个3个字母的序列,该序列应该等于abcxyz时间,这是不可能的。

您正在寻找的是

^(?=.*abc)(?=.*xyz)

或者,要支持多行输入,请添加DOTALL修饰符(?s)(以便.也可以匹配换行符):

(?s)^(?=.*abc)(?=.*xyz)

这些将匹配以任何顺序同时包含abcxyz的字符串。

请参阅R demo

a <- c("abcxyz", "abcdef", "defxyz", "abcdefxyz", "xyzdefabc")
grep("^(?=.*abc)(?=.*xyz)", a, ignore.case=TRUE, perl=TRUE)
## => [1] 1 4 5