R:环顾四周

R: lookaround within lookaround

我需要匹配前面有两个不同元音的任何 'r'。例如,'our' 或 'pear' 会匹配,但 'bar' 或 'aar' 不会。我确实设法匹配了两个不同的元音,但我仍然无法将其作为随后 'r' 的后视条件 (...)。 (?<=...)r...\Kr 都没有产生任何结果。有什么想法吗?

x <- c('([aeiou])(?!\1)(?=(?1))')
y <- c('our','pear','bar','aar')
y[grepl(paste0(x,collapse=''),y,perl=T)]
## [1] "our"  "pear"`

这是一个不太优雅的解决方案:

y[grepl("[aeiou]{2}r", y, perl=T) & !grepl("(.)\1r", y, perl=T)]

可能有一些极端案例失败,其中第一组与第二组在不同的位置匹配(必须考虑这一点),但可以帮助您入门。

这两个解决方案似乎有效:

为什么不方式:

x <- '(?<=a[eiou]|e[aiou]|i[aeou]|o[aeiu]|u[aeio])r'
y[grepl(x, y, perl=T)]

\K方式:

x <- '([aeiou])(?!\1)[aeiou]\Kr'
y[grepl(x, y, perl=T)]

为什么不方式变体(可能更有效,因为它搜索之前的"r"):

x <- 'r(?<=a[eiou]r|e[aiou]r|i[aeou]r|o[aeiu]r|u[aeio]r)'

或快速排除前面没有两个元音的 "r" (无需测试整个交替)

x <- 'r(?<=[aeiou][aeiou]r)(?<=a[eiou]r|e[aiou]r|i[aeou]r|o[aeiu]r|u[aeio]r)'

正如 HamZa 在评论中指出的那样,使用 skip 和 fail 动词是一种实现我们想要的方式。基本上我们告诉它忽略我们有两个相同元音后跟 "r"

的情况
# The following is the beginning of the regex and isn't just R code
# the ([aeiou]) captures the first vowel, the \1 references what we captured
# so this gives us the same vowel two times in a row
# which we then follow with an "r"
# Then we tell it to skip/fail for this
([aeiou])\1r(*SKIP)(*FAIL)

现在我们告诉它跳过这些情况,所以现在我们告诉它 "or cases where we have two vowels followed by an 'r'",因为我们已经排除了这两个元音相同的情况,这将得到我们想要的。

|[aeiou]{2}r

把它放在一起我们最终得到

y <- c('our','pear','bar','aar', "aa", "ae", "are", "aeer", "ssseiras")
grep("([aeiou])\1r(*SKIP)(*FAIL)|[aeiou]{2}r", y, perl = TRUE, value = TRUE)
#[1] "our"    "pear"    "sseiras"

另一个通过否定前瞻断言。

> y <- c('our','pear','bar','aar', "aa", "ae", "are", "aeer", "ssseiras")
> grep("(?!(?:aa|ee|ii|oo|uu)r)[aeiou][aeiou]r", y, perl=TRUE, value=TRUE)
[1] "our"      "pear"     "ssseiras"

> grep("(?!aa|ee|ii|oo|uu)[aeiou][aeiou]r", y, perl=TRUE, value=TRUE)
[1] "our"      "pear"     "ssseiras"

(?!aa|ee|ii|oo|uu) 断言匹配中的前两个字符不会是 aaee 或 .... 或 uu。所以这个 [aeiou][aeiou] 会匹配其他任何两个元音,但不会重复。这就是为什么我们首先设置条件。 r 匹配元音后的 r。