¿El modificador de expresión regular de Perl / m coincide de manera diferente en Windows?

StackOverflow https://stackoverflow.com/questions/214517

  •  03-07-2019
  •  | 
  •  

Pregunta

Las siguientes declaraciones Perl se comportan de manera idéntica en máquinas Unixish. ¿Se comportan de manera diferente en Windows? Si es así, ¿es por la magia \ n?

  split m/\015\012/ms, $http_msg;
  split m/\015\012/s, $http_msg;

Obtuve un error en uno de mis módulos CPAN de un probador de humo Win32. Parece que es un problema \ r \ n vs \ n. Uno de los cambios que hice recientemente fue agregar // m a mis expresiones regulares.

¿Fue útil?

Solución

Para estas expresiones regulares:

m/\015\012/ms
m/\015\012/s

Ambos / m y / s no tienen sentido.

  • / s: hace que . coincida con \ n también. Su expresión regular no contiene .
  • / m: hace que ^ y $ coincidan al lado de \ n incrustado en la cadena. Su expresión regular no contiene ^ ni $ , ni sus sinónimos.

Lo que sí es posible es que si el controlador de entrada (socket?) funciona en modo de texto, los caracteres \ r ( \ 015 ) se eliminarán en Windows.

Entonces, ¿qué hacer? Sugiero que los caracteres \ 015 sean opcionales y que se dividan en contra

/\015?\012/

No es necesario para / m, / s ni siquiera para el m // . Esos son solo cultos de carga.

Otros consejos

No hay ningún \ n mágico. Tanto \ n como \ r siempre significan exactamente un carácter, y en todas las plataformas basadas en ASCII que son \ cJ y \ cM respectivamente. (Las excepciones son las plataformas EBCDIC (por razones obvias) y MacOS Classic (donde \ n y \ r significan \ cM ).)

La magia que ocurre en Windows es que cuando se hace E / S a través de un identificador de archivo que está marcado como en modo de texto, \ r \ n se traduce a \ n al leer y viceversa al escribir. (Además, se considera que \ cZ significa fin de archivo: ¡sorpresa!) Esto se hace en la capa de la biblioteca en tiempo de ejecución de C.

Necesitas binmode para corregirlo.

También debe eliminar los modificadores / s y / m de su patrón: ya que no utiliza los metacaracteres cuyo comportamiento modifican (. y el par ^ / $ , respectivamente), no hacen nada - carga de carga.

¿Por qué agregó el / m ? ¿Estás tratando de dividir en línea? Para hacer eso con / m necesita usar ^ o $ en la expresión regular:

my @lines = split /^/m, $big_string;

Sin embargo, si desea tratar una cadena grande como líneas, simplemente abra un identificador de archivo en una referencia al escalar:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top