2009-09-09 7 views
0

j'ai cette condition dans un script Perl:problème expression régulière Perl

if ($lnFea =~ m/^(\d+) qid\:([^\s]+).*?\#docid = ([^\s]+) inc = ([^\s]+) prob = ([^\s]+)$/) 

et lnFea $ représente ce genre de ligne:

0 qid: 7968 1: 0,000000 2: 0,000000 3: 0,000000 4: 0,000000 5: 0,000000 6: 0,000000 7: 0,000000 8: 0,000000 9: 0,000000 10: 0,000000 11: 0,000000 12: 0,000000 13: 0,000000 14: 0,000000 15: 0,000000 16: 0,005175 17: 0,000000 18: 0,181818 19: 0,000000 20: 0,003106 21: 0,000000 22: 0,000000 23: 0,000000 24: 0,000000 25: 0,000000 26: 0,000000 27: 0,000000 28: 0,000000 29: 0,000000 30: 0,000000 31: 0,000000 32: 0,000000 33: 0,000000 34: 0,000000 35: 0,000000 36: 0,000000 37 : 0.000000 38: 0.000000 39: 0.000000 40: 0.000000 41: 0.000000 42: 0.000000 43: 0.055556 44: 0.000000 45: 0.000000 46: 0.000000 #docid = GX000-00-0000000 inc = 1 prob = 0.0214125

Le problème est que le si est vrai sur Windows mais faux sur Linux (Fedora 11). Les deux systèmes utilisent la version la plus récente de Perl. Alors, quelle est la raison de ce problème?

Répondre

10

En supposant que $InFea est lu à partir d'un fichier, je parie que le fichier est au format DOS. Cela provoquerait l'ancre $ pour empêcher la correspondance sur Linux en raison des différences dans les fins de ligne entre ces plates-formes. La transformation de nouvelle ligne automagique de Perl ne fonctionne que pour les fichiers texte natifs de la plate-forme. Si le fichier d'entrée est au format DOS, la boîte Linux verra un retour chariot avant la fin de la ligne.

Il est probablement préférable de convertir le fichier d'entrée au format natif pour chaque plate-forme. Si ce n'est pas possible, vous devez utiliser le handle de fichier (empêchant Perl d'effectuer des transformations de nouvelle ligne) avant de le lire et de prendre en compte les différentes séquences de nouvelle ligne dans la regex et partout ailleurs où les données sont utilisées.

+0

+1 Je suis d'accord. L'OP doit convertir le format de fin de ligne ou inclure une séquence CRLF optionnelle dans l'expression régulière. –

+0

+1 J'allais dire la même chose. Si vous supprimez le $ à la fin de votre regex, cela peut fonctionner si c'est le cas. –

+0

Alternativement: s/\ r // g et chomp() pour supprimer tous les caractères EOL et accepter les fins de ligne mixtes arbitraires. Mais Mark a probablement raison, que le $ n'ajoute aucune valeur à l'expression rationnelle et pourrait être éliminé. L'acceptation d'une syntaxe de super-ensemble n'est généralement pas un bogue, et les expressions régulières font des analyseurs de validité médiocres. Enfin: pas besoin d'échapper vos caractères ':' et '#' dans cette regex. –