regular pattern not negative look literal exist example does around regex r backreference

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.