Question

Les instructions Perl suivantes se comportent de manière identique sur les ordinateurs Unix. Est-ce qu'ils se comportent différemment sous Windows? Si oui, est-ce dû à la magie \ n?

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

J'ai un échec sur l'un de mes modules CPAN à partir d'un testeur de fumée Win32. Cela semble être un problème \ r \ n vs \ n. Un changement que j'ai apporté récemment a été d'ajouter // m à mes expressions rationnelles.

Était-ce utile?

La solution

Pour ces regex:

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

Les deux / m et / s n'ont pas de sens.

  • / s: fait que . correspond également à \ n . Votre regex ne contient pas .
  • / m: établit une correspondance entre ^ et $ en regard de \ n incorporé dans la chaîne. Votre regex ne contient pas ^ ni $ , ni leurs synonymes.

Ce qui est possible est en effet si votre descripteur d’entrée (socket?) fonctionne en mode texte, les caractères \ r ( \ 015 ) auront été supprimés sous Windows.

Alors, que faire? Je suggère de rendre les caractères \ 015 facultatifs et de les scinder en fonction de

/\015?\012/

Pas besoin de / m, / s ou même du premier m // . Ce ne sont que culte du fret.

Autres conseils

Il n'y a pas de magie \ n . \ n et \ r signifient toujours exactement un caractère, et sur toutes les plates-formes basées sur ASCII, \ cJ et \ cM respectivement. (Les exceptions sont les plates-formes EBCDIC (pour des raisons évidentes) et MacOS Classic (où \ n et \ r signifient tous les deux \ cM ).)

La magie qui se produit sous Windows est que, lorsque vous effectuez des E / S via un descripteur de fichier marqué comme étant en mode texte, \ r \ n est traduit en \ n lors de la lecture et vice versa lors de l'écriture. (En outre, \ cZ signifie "surprise de fin de fichier"!). Ceci est effectué au niveau de la couche de la bibliothèque d'exécution C.

Vous devez binmode votre socket pour y remédier.

Vous devez également supprimer les modificateurs / s et / m de votre modèle: puisque vous n'utilisez pas les méta-caractères dont ils modifient le comportement (. et la paire ^ / $ , respectivement), ils ne font rien & # 8211; culte de la cargaison.

Pourquoi avez-vous ajouté le / m ? Est-ce que vous essayez de vous séparer en ligne? Pour faire cela avec / m , vous devez utiliser ^ ou $ dans la regex:

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

Cependant, si vous souhaitez traiter une grosse chaîne comme des lignes, ouvrez simplement un descripteur de fichier sur une référence au scalaire:

open my $string_fh, '<', \ $big_string;
while( <$string_fh> ) {
    ... process a line
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top