2013-03-31 6 views
0

Je suis plutôt nouveau au concept de Regex. Je comprends l'expression rationnelle de base que j'utilise dans le script bash. L'extrait de code suivant provient d'un programme que j'écris pour mettre à jour automatiquement les plugins Wordpress sur le serveur. Quoi qu'il en soit, le concept est que ce morceau de code fait partie d'un sous-programme qui récursive via les fichiers .php dans un répertoire, et essaie de faire correspondre les fichiers en commençant par "Version:", "version:", "* Version: "etc à partir du fichier, et si pattern est trouvé, un autre sub essaye alors d'extraire la valeur qui suit le caractère": "pour obtenir le numéro de version correct.Perl erreur logique regex

$searchpath=$path."/".$plugins[$i]; 
     @files = <$searchpath/*.php>; 
     print "Search path is ".$searchpath."\n"; 
OUT: foreach $file (@files) 
     { 
      print "Checking alternate php file: ".$file."\n"; 
      open(txt, $file); 
      while($line = <txt>) 
      { 
       for ($line) 
       { 
       s/^\s+//; 
       s/\s+$//; 
       } 
       if ($line =~ /^Version:|^version:|^\* Version:|\sVersion:/) 
       { 
        print "Version found in file ".$file."\n"; 
        $varfound=1;  
        close(txt); 
        $ver=&read_extract($file); 
        print $ver."\n"; 
        $pluginversion[$i]=$ver; 
        print "Array Num ".$i." Stored plugin name:".$plugins[$i]." Version found ".$ver." Version stored ".$pluginversion[$i]."\n"; 
        last OUT; 
       } 
      } 
     } 

Le problème est que je semble avoir une erreur dans la logique et le fichier correspond effectivement \ n « phpversion(). « », Version enregistrée ». phpversion(). "\ n" pour la requête de recherche Avec mes connaissances limitées, je trouve difficile de comprendre ce qui ne va pas, et je serais impatient de recevoir des conseils.

Les autres sous-marins visés sont inclus ci-dessous:

sub read_extract 
{ 
    my $pl_version=""; 
    open(txt, my $file=$_[0]); 
    while($line = <txt>) 
    { 
     for ($line) 
     { 
     s/^\s+//; 
     s/\s+$//; 
     }   
     if ($line =~ /^Version:|^version:|^\* Version:|\sVersion:/) 
     { 
      $pl_version=&extract_version($line); 
     } 
    } 
    close(txt); 
    $pl_version; 
} 

sub extract_version 
{ 
    my $line=$_[0]; 
    $string=substr($line,rindex($line, ":")+1); 
    for ($string) 
    { 
    s/^\s+//; 
    s/\s+$//; 
    } 
    $string; 
} 

Si mon sous-programme est nécessaire en entier, je peux l'inclure. Cependant mes lignes de débogage montrent ceci:

Processing xcloner-backup-and-restore...Search path is /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/admin.cloner.html.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/admin.cloner.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/admin.xcloner-backupandrestore.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/admin.xcloner.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/cloner.config.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/cloner.cron.php 
Checking alternate php file: /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/cloner.functions.php 
Version found in file /var/www/virtual/joel.co.in/vettathu.com/htdocs/wp-content/plugins/xcloner-backup-and-restore/cloner.functions.php 
" . phpversion() . "\n"; 
Array Num 26 Stored plugin name:xcloner-backup-and-restore Version found " . phpversion() . "\n"; Version stored " . phpversion() . "\n"; 

qui semble être où l'erreur est.

Répondre

1

Eh bien, c'est beaucoup de code redondant là-bas. Si vous avez déjà la ligne, pourquoi devez-vous fermer le fichier et retrouver la ligne? Tout ce que vous devez faire est de capturer la chaîne lorsque vous trouvez la ligne:

if ($line =~ /^\*?\s?Version:(.*)/i) { 
    my $version = $1; 

Ainsi, en utilisant le modificateur /i, votre match est insensible à la casse. En plaçant ? après \* et \s ils peuvent correspondre 0 ou 1 fois. En utilisant (.*) le reste de la ligne est capturé à $1.

Votre expression régulière ne possédait pas d'ancre de début de ligne ^ dans la dernière correspondance, ce que je supposais être une faute de frappe. Sinon, vous pouvez simplement changer la regex à /\bVersion:(.*)/i. Et le \b est seulement utile pour éviter les correspondances partielles, telles que subversion: foo.

+0

Est-ce que le \ * ne correspond pas à l'expression si elle commence par *? Je suppose que je dois le modifier pour inclure un autre OU comme '/^\ s Version: (. *) /' Est-ce que le/je travaillerais même si j'ai OU comme '$ line = ~/^ \ *? \ S? Version: (. *) |^\ S? Version: (. *)/I'? – Droidzone

+0

Je ne sais pas ce que signifie «inclure autre ou similaire», mais non, «\ *?» Signifie «correspondre à un littéral * 0 ou 1 fois». Vous pouvez également faire '[* \ s] *' pour rendre tous ces caractères facultatifs. – TLP

+0

@Droidzone Non ... ce n'est pas ça. '* 'étant optionnel signifie qu'il n'a pas besoin d'être là ... donc' \ *? \ s? | \ s? 'signifie exactement la même chose que' \ *? \ s? '. – TLP