regulares para nombres net lenguaje expresiones espacio concatenar caracteres cadena basicas php javascript python regex perl

php - nombres - Alternativas look-behind-assertion de longitud variable para expresiones regulares



expresiones regulares vb net (5)

La expresión regular que muestre encontrará cualquier instancia de bar que no esté precedida por foo .

Una alternativa simple sería emparejar primero foo con la cadena y encontrar el índice de la primera aparición. Luego busca bar , y mira si puedes encontrar una ocurrencia que viene antes de ese índice.

Si quieres encontrar instancias de bar que no estén directamente precedidas por foo , también podría proporcionar una expresión regular para eso (sin usar lookbehind), pero será muy feo. Básicamente, invierta el sentido de /foo/ - ie /[^f]oo|[^o]o|[^o]|$/ .

¿Hay una implementación de expresiones regulares en Python / PHP / JavaScript que admita lookbehind-assertion de longitud variable?

/(?<!foo.*)bar/

¿Cómo puedo escribir una expresión regular que tenga el mismo significado, pero que no use una afirmación lookbehind?

¿Hay alguna posibilidad de que este tipo de afirmación se implemente algún día?

Las cosas son mucho mejores de lo que pensaba.

Actualizar:

(1) Hay implementaciones de expresiones regulares que soportan lookbehind-assertion de longitud variable ya.

La regex módulo de Python (no estándar, sino el módulo de regex adicional) admite tales afirmaciones (y tiene muchas otras funciones geniales).

>>> import regex >>> m = regex.search(''(?<!foo.*)bar'', ''f00bar'') >>> print m.group() bar >>> m = regex.search(''(?<!foo.*)bar'', ''foobar'') >>> print m None

Fue una gran sorpresa para mí que haya algo en expresiones regulares que Perl no puede hacer y Python puede hacerlo. Probablemente, hay una implementación de "expresión regular mejorada" para Perl también?

(Gracias y +1 a MRAB).

(2) Hay una característica interesante /K en las expresiones regulares modernas.

Este símbolo significa que cuando haces una sustitución (y desde mi punto de vista el caso de uso más interesante de las aserciones es la sustitución), no se deben cambiar todos los caracteres que se encontraron antes de /K

s/unchanged-part/Kchanged-part/new-part/x

Eso es casi como una afirmación de mirar hacia atrás, pero no tan flexible, por supuesto.

Más sobre /K :

Por lo que yo entiendo, no puedes usar / K dos veces en la misma expresión regular. Y no puedes decir hasta qué punto quieres "matar" a los personajes que has encontrado. Eso es siempre hasta el comienzo de la línea.

(Gracias y +1 a ikegami).

Mis preguntas adicionales:

  • ¿Es posible decir qué punto debe ser el punto final del efecto /K ?
  • ¿Qué hay de las implementaciones mejoradas de expresiones regulares para Perl / Ruby / JavaScript / PHP? Algo así como regex para Python.

La mayoría de las veces, puede evitar la búsqueda de longitud variable utilizando /K

s/(?<=foo.*)bar/moo/s;

sería

s/foo.*/Kbar/moo/s;

Las miradas negativas son un poco más complicadas.

s/(?<!foo.*)bar/moo/s;

sería

s/^(?:(?!foo).)*/Kbar/moo/s;

porque (?:(?!STRING).)* es para STRING como [^CHAR]* es para CHAR .

Si solo está buscando coincidencias, es posible que ni siquiera necesite la /K

/foo.*bar/s /^(?:(?!foo).)*bar/s


Para Python hay una implementación de expresiones regulares que admite lookbehinds de longitud variable:

regex

Está diseñado para ser compatible con versiones anteriores con el módulo de re estándar.


Puede invertir la cadena Y el patrón y usar la longitud variable lookahead

(rab(?!/w*oof)/w*)

coincide en negrita:

Raboof rab7790oof raboo rabof Rab rabo raboooof rabo

Solución original hasta donde yo sé por:

Jeff ''japhy'' Pinyan


foo.*|(bar)

Si foo está en la cadena primero, la expresión regular coincidirá, pero no habrá grupos.

De lo contrario, encontrará una bar y lo asignará a un grupo.

Entonces puede usar esta expresión regular y buscar los resultados en los grupos encontrados:

>>> import re >>> m = re.search(''foo.*|(bar)'', ''f00bar'') >>> if m: print(m.group(1)) bar >>> m = re.search(''foo.*|(bar)'', ''foobar'') >>> if m: print(m.group(1)) None >>> m = re.search(''foo.*|(bar)'', ''fobas'') >>> if m: print(m.group(1)) >>>

Source.