2009-09-05 5 views
3

J'ai des problèmes de perl regex correspondant à un script réseau que j'ai, j'ai réussi à mettre le comportement dans un petit extrait.Pourquoi mon expression régulière pour correspondre à un numéro de version ne fonctionne pas?

Prenez cet extrait Perl pour Perl 5.10.0 dans Debian:

#!/usr/bin/perl 
use warnings; 
use strict; 

my $line = "Version: 0\r\n"; 
my($version) = $line =~ m/^Version:(\s\d+)\r\n$/; 
print "1st failed \n" if not $version; 
($version) = $line =~ m/^Version:\s(\d+)\r\n$/; 
print "2nd failed \n" if not $version; 
($version) = $line =~ m/^Version:\ (\d+)\r\n$/; 
print "3th failed \n" if not $version; 

Avec cette sortie:

2nd failed 
3th failed 

Apparemment, la seule différence entre le 1er et le 2e se déplace l'espace hors de l'extrait pattern, qui en théorie ne devrait pas modifier la regex, juste la partie retournée.

Je ne comprends pas pourquoi les 2ème et 3ème ne fonctionnent pas exactement comme la première. Si vous supprimez les parenthèses dans la version $ n'est pas le même script, vous n'obtenez pas le résultat correspondant, vous obtenez le résultat booléen de l'op, pour obtenir le résultat correspondant, vous devez le recevoir dans un unaire (une seule chaîne pour correspondre) tuple.

Répondre

12

Le problème est que vous testez pour boolean true, car dans les deux derniers cas, vous extrayez une valeur de chaîne false (chaîne '0'). Essayez ceci:

$line = "Version: 0\r\n"; 
my $version; 
($version) = $line =~ m/^Version:(\s\d+)\r\n$/; 
print "1st failed \n" unless defined $version; 
($version) = $line =~ m/^Version:\s(\d+)\r\n$/; 
print "2nd failed \n" unless defined $version; 
($version) = $line =~ m/^Version:\ (\d+)\r\n$/; 
print "3th failed \n" unless defined $version; 
+0

Vous avez certainement raison, cela ne se produirait pas avec "Version: 1", le motif apparié est la chaîne "0", qui a un résultat booléen de faux. Comment n'ai-je pas remarqué ça avant? : | –

+1

Vous n'avez probablement pas remarqué parce que le premier match a également un '0'. La différence est que la première correspondance capture '[] 0', et la présence de l'espace vide provoque l'évaluation de la chaîne * that * comme vraie. C'est pourquoi je ne l'ai pas vu tout de suite, au moins. – Telemachus

+0

"Échec d'impression" \ n "à moins que ($ version) = $ line = ~ ...' "puisse également fonctionner –

2

Vous ne testez pas l'opérateur de correspondance. Si vous voulez voir si un match échoue, tester le match:

if($line =~ m/(...)/) { 
    $version = $1; 
    } 

Vous pouvez au moins vérifier que lors du débogage pour réduire le problème à la partie qui échoue.

Travailler avec des données différentes, comme:

Version: 1\r\n 

aurait montré vous un comportement différent où vous avez sans doute remarqué que si échoué que lorsque la version était 0. Cela aurait pu allumé dans votre tête quelques ampoules:

Questions connexes