Pergunta

As seguintes declarações Perl se comportam de forma idêntica em máquinas Unixish. Será que eles se comportam de forma diferente no Windows? Se sim, é por causa da magia \ n?

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

Eu tenho um falha em um dos meus módulos do CPAN de uma fumaça tester Win32. Parece que é uma \ r \ n vs \ n questão. Uma mudança que eu fiz recentemente foi adicionar // m aos meus expressões regulares.

Foi útil?

Solução

Para estas expressões regulares:

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

Ambos / m / s e são insignificantes.

  • / S: faz . jogo \n também. Seu regex não contém .
  • / m: faz ^ e combinar $ ao lado \n incorporado na cadeia. Seu regex não contém ^ nem $, ou seus sinônimos.

O que é possível é, de fato, se o seu identificador de entrada (socket?) Funciona em modo de texto, o \r (\015) caracteres serão eliminados no Windows.

Então, o que fazer? Sugiro fazer o \015 caracteres opcional e dividida contra

/\015?\012/

Não há necessidade de / m, / s ou mesmo o m// líder. Essas são culto à carga apenas.

Outras dicas

Não há \n magia. Ambos \n e \r sempre significa exatamente um caractere, e em todas as plataformas baseadas em ASCII que é \cJ e \cM respectivamente. (As exceções são plataformas EBCDIC (por razões óbvias) e MacOS clássico (onde \n e \r tanto \cM média).)

A mágica que acontece no Windows é que ao fazer I / O por meio de um identificador de arquivo que está marcado como estando em modo texto, \r\n é traduzido para \n após a leitura e vice-versa sobre a escrita. (Além disso, \cZ é tomado para significar fim-de-arquivo - surpresa). Isto é feito na camada de biblioteca C tempo de execução

Você precisa binmode sua tomada para corrigir isso.

Você também deve remover os modificadores /s e /m de seu padrão: desde que você não use os meta-caracteres cujo comportamento eles modificam (. eo par ^ / $, respectivamente), eles não fazem nada - culto da carga

Por que você adicione o /m? Você está tentando dividir em linha? Para fazer isso com /m você precisa usar ^ ou $ no regex:

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

No entanto, se você quiser tratar uma grande cadeia como linhas, basta abrir uma filehandle em uma referência ao escalar:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top