regular one non expressions examples capturing regex perl lookbehind

regex - one - ¿Puede salvar mi ejemplo de mirada negativa para comentar números?



regex one (3)

En el capítulo "Advanced Regular Expresssion" en Mastering Perl , tengo un ejemplo roto para el que no puedo encontrar una buena solución. Tal vez el ejemplo sea tratar de ser demasiado inteligente por su propio bien, pero tal vez alguien pueda arreglarlo por mí. Podría haber una copia gratuita del libro en él para arreglos de trabajo. :)

En la sección que trata sobre los aspectos de búsqueda, quise usar un aspecto negativo para implementar una rutina de verificación de números con porciones fraccionarias. El punto era usar una mirada negativa, porque ese era el tema.

Estúpidamente hice esto:

$_ = ''$1234.5678''; s/(?<!/./d)(?<=/d)(?=(?:/d/d/d)+/b)/,/g; # $1,234.5678

El (?<!/./d) afirma que el bit anterior al (?=(?:/d/d/d)+/b) no es un punto decimal y un dígito.

Lo estúpido no es esforzarse lo suficiente para romperlo. Al agregar otro dígito al final, ahora hay un grupo de tres dígitos no precedidos por un punto decimal y un dígito:

$_ = ''$1234.56789''; s/(?<!/./d)(?<=/d)(?=(?:/d/d/d)+/b)/,/g; # $1,234.56,789

Si Lookbhinds pudiera tener un ancho variable en Perl, esto hubiera sido realmente fácil. Pero no pueden.

Tenga en cuenta que es fácil hacer esto sin una mirada negativa, pero ese no es el punto del ejemplo. ¿Hay alguna manera de salvar este ejemplo?


No creo que esto sea lo que está buscando (especialmente porque se ha eliminado la afirmación de look-behind negativo), pero supongo que su única opción es absorber los decimales como en este ejemplo:

s/ (?: (?<=/d) (?=(?:/d/d/d)+/b) | ( /d{0,3} /. /d+ ) ) / $1 ? $1 : '','' /exg;

PD: Creo que es un buen ejemplo cuando no se utiliza como el primero en el libro, ya que demuestra algunos de los escollos y limitaciones de las aseveraciones de búsqueda.


No creo que sea posible sin una forma de look-behind de ancho variable. La adición de la afirmación /K en 5.10 proporciona una manera de falsear el look-behind positivo de ancho variable. Lo que realmente necesitamos es un look-behind negativo de ancho variable pero con un poco de creatividad y mucha fealdad podemos hacer que funcione:

use 5.010; $_ = ''$1234567890.123456789''; s/(?<!/.)(?:/b|/G)/d+?/K(?=(?:/d/d/d)+/b)/,/g; say; # $1,234,567,890.123456789

Si alguna vez hubo un patrón que pidió la notación /x es este:

s/ (?<!/.) # Negative look-behind assertion; we don''t want to match # digits that come after the decimal point. (?: # Begin a non-capturing group; the contents anchor the /d # which follows so that the assertion above is applied at # the correct position. /b # Either a word boundary (the beginning of the number)... | # or (because /b won''t match at subsequent positions where # a comma should go)... /G # the position where the previous match left off. ) # End anchor grouping /d+? # One or more digits, non-greedily so the match proceeds # from left to right. A greedy match would proceed from # right to left, the /G above wouldn''t work, and only the # rightmost comma would get placed. /K # Keep the preceding stuff; used to fake variable-width # look-behind # <- This is what we match! (i.e. a position, no text) (?= # Begin a positive look-ahead assertion (?:/d/d/d)+ # A multiple of three digits (3, 6, 9, etc.) /b # A word (digit) boundary to anchor the triples at the # end of the number. ) # End positive look-ahead assertion. /,/xg;


Si tiene que publicar en preguntando si alguien puede averiguar cómo hacer esto con un aspecto negativo, entonces obviamente no es un buen ejemplo de este aspecto negativo. Sería mejor que piense en un nuevo ejemplo en lugar de intentar rescatar este.

En ese espíritu, ¿qué tal un corrector ortográfico automático?

s/(?<![Cc])ei/ie/g; # Put I before E except after C

(Obviamente, esa no es una regla difícil y rápida en inglés, pero creo que es una aplicación más realista de la mirada negativa que se muestra detrás).