R:环顾四周

das*_*asf 33 regex backreference r

我需要匹配前面有两个不同元音的'r'.例如,'我们'或'梨'将匹配,但'bar'或'aar'不匹配.我确实设法匹配两个不同的元音,但我仍然不能使...后续'r'的lookbehind 条件().既(?<=...)r不会...\\Kr产生任何结果.有任何想法吗?

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

Cas*_*yte 21

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

何不方式:

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

\K方式:

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

何不方式变型(因为之前搜索"R"可能会更有效):

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

或快速排除"r"之前没有两个元音(不测试整个交替)

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

  • 我们也可以使用递归来缩短*模式.不是非常友善的友好:`([aeiou])(?!\\ 1)(?1)\\ Kr` (2认同)

Das*_*son 15

正如HamZa在评论中指出的,使用跳过和失败动词是我们想要的一种方式.基本上我们告诉它忽略我们有两个相同的元音后跟"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)
Run Code Online (Sandbox Code Playgroud)

现在我们告诉它跳过这些情况所以现在我们告诉它"或者我们有两个元音后跟一个'r'的情况",因为我们已经消除了这两个元音相同的情况,这将得到我们想要的东西.

|[aeiou]{2}r
Run Code Online (Sandbox Code Playgroud)

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

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"
Run Code Online (Sandbox Code Playgroud)


Bro*_*ieG 6

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

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

可能有一些角落案例失败,其中第一组在不同位置匹配而不是第二组(将不得不考虑这一点),但有些东西可以让你开始.