Подтвердить что ты не робот

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"`
4b9b3361

Ответ 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, который следует за гласными.