R: смотреть в поисках
Мне нужно сопоставить любые "r", которым предшествуют две разные гласные. Например, "наша" или "груша" будет соответствовать, но "бар" или "аар" не будут. Мне удалось сопоставить два разных гласных, но я все еще не могу сделать это условие (...
) lookbehind для последующего "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"`
Ответы
Ответ 1
Кажется, что эти два решения работают:
почему не путь:
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)'
Ответ 2
Как указывает 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)
Теперь мы сказали ему пропустить эти случаи, так что теперь мы говорим об этом "или случаях, когда у нас есть две гласные, за которыми следует" 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"
Ответ 3
Ниже представлено менее элегантное решение:
y[grepl("[aeiou]{2}r", y, perl=T) & !grepl("(.)\\1r", y, perl=T)]
Вероятно, есть некоторые ошибки в случае с короткими случаями, когда первый набор соответствует в другом месте, чем второй набор (нужно подумать об этом), но что-то, чтобы вы начали.
Ответ 4
Другой с отрицательным утверждением.
> 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)
утверждает, что первые два символа в матче не будут aa
или ee
или.... или uu
. Таким образом, этот [aeiou][aeiou]
будет соответствовать любым двум гласным другим, но он не будет повторяться. Вот почему мы сначала устанавливаем условие. r
совпадает с r, который следует за гласными.