regex - pattern - R: lookaround dentro de lookaround
regex r (4)
Necesito hacer coincidir cualquier ''r'' que esté precedida por dos vocales diferentes. Por ejemplo, ''nuestro'' o ''pera'' coincidirían pero ''bar'' o ''aar'' no lo harían. Me las arreglé para hacer coincidir las dos vocales diferentes, pero todavía no puedo hacer que la condición ( ...
) de mirar hacia atrás para la ''r'' resultante. Ni (?<=...)r
ni ...//Kr
produce ningún resultado. ¿Algunas ideas?
x <- c(''([aeiou])(?!//1)(?=(?1))'')
y <- c(''our'',''pear'',''bar'',''aar'')
y[grepl(paste0(x,collapse=''''),y,perl=T)]
## [1] "our" "pear"`
Aquí hay una solución menos que elegante:
y[grepl("[aeiou]{2}r", y, perl=T) & !grepl("(.)//1r", y, perl=T)]
Probablemente haya algunas fallas en las esquinas donde el primer conjunto coincide en una ubicación diferente a la del segundo (tendrá que pensar en eso), pero algo para comenzar.
Como señala HamZa en los comentarios, utilizar verbos omitidos y omisos es una forma de hacer lo que queremos. Básicamente le decimos que ignore los casos en los que tenemos dos vocales idénticas seguidas de "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)
Ahora le dijimos que saltee esos casos, así que ahora lo contamos "o casos en los que tenemos dos vocales seguidas por una ''r''" y como ya eliminamos los casos en que esas dos vocales son iguales, obtendremos lo que queremos.
|[aeiou]{2}r
Poniéndolo juntos terminamos con
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"
Estas dos soluciones parecen funcionar:
el porqué no manera:
x <- ''(?<=a[eiou]|e[aiou]|i[aeou]|o[aeiu]|u[aeio])r''
y[grepl(x, y, perl=T)]
la forma /K
:
x <- ''([aeiou])(?!//1)[aeiou]//Kr''
y[grepl(x, y, perl=T)]
La variante por qué no hacerlo (puede ser más eficiente porque antes busca "r"):
x <- ''r(?<=a[eiou]r|e[aiou]r|i[aeou]r|o[aeiu]r|u[aeio]r)''
o para excluir rápidamente "r" no precedida por dos vocales (sin para probar la alternancia completa)
x <- ''r(?<=[aeiou][aeiou]r)(?<=a[eiou]r|e[aiou]r|i[aeou]r|o[aeiu]r|u[aeio]r)''
Otro a través de una afirmación negativa de anticipación.
> 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)
afirma que los dos primeros caracteres en el partido no serán aa
o ee
o ... o uu
. Entonces este [aeiou][aeiou]
igualaría dos vocales diferentes pero no se repetiría. Es por eso que establecemos la condición al principio. r
coincide con el r que sigue a las vocales.