Domanda

Le seguenti istruzioni Perl si comportano in modo identico su macchine Unixish. Si comportano diversamente su Windows? Se sì, è a causa della magia \ n?

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

Ho ricevuto un fallimento su uno dei miei moduli CPAN da un rilevatore di fumo Win32. Sembra che sia un problema \ r \ n vs \ n. Una modifica che ho apportato di recente è stata l'aggiunta di // m ai miei regex.

È stato utile?

Soluzione

Per queste regex:

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

Sia / m che / s sono privi di significato.

  • / s: fa corrispondere anche . a \ n . Il tuo regex non contiene .
  • / m: fa corrispondere ^ e $ accanto a \ n incorporato nella stringa. Il tuo regex non contiene né ^ $ , né i loro sinonimi.

Ciò che è possibile è effettivamente se il tuo handle di input (socket?) funziona in modalità testo, i caratteri \ r ( \ 015 ) saranno stati eliminati su Windows.

Quindi, cosa fare? Suggerisco di rendere facoltativi i caratteri \ 015 e dividerli con

/\015?\012/

Non è necessario per / m, / s o persino il m // principale. Quelli sono solo cult di merci.

Altri suggerimenti

Non esiste un \ n magico. Sia \ n che \ r significano sempre esattamente un carattere e su tutte le piattaforme basate su ASCII che sono \ cJ e \ cM rispettivamente. (Le eccezioni sono piattaforme EBCDIC (per ovvie ragioni) e MacOS Classic (dove \ n e \ r significano entrambi \ cM ).)

La magia che si verifica su Windows è che quando si esegue l'I / O tramite un handle di file contrassegnato come in modalità testo, \ r \ n viene tradotto in \ n su lettura e viceversa su scrittura. (Inoltre, \ cZ significa sorpresa del fine del file & # 8211; sorpresa!) Questo viene fatto a livello della libreria di runtime C.

Per risolvere il problema devi binmode il tuo socket per risolvere il problema.

Dovresti anche rimuovere i modificatori / s e / m dal tuo pattern: poiché non usi i meta-personaggi il cui comportamento modificano (. e la coppia ^ / $ , rispettivamente), non fanno nulla & # 8211; culto delle merci.

Perché hai aggiunto il / m ? Stai cercando di dividere in linea? Per farlo con / m devi usare ^ o $ nella regex:

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

Tuttavia, se si desidera trattare una stringa grande come linee, è sufficiente aprire un filehandle su un riferimento allo scalare:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top