【问题标题】:Perl regex logic errorPerl 正则表达式逻辑错误
【发布时间】:2013-03-31 19:14:25
【问题描述】:

我对正则表达式的概念相当陌生。我了解我在 bash 脚本中使用的基本正则表达式。以下 sn-p 代码来自我正在编写的用于自动更新服务器上的 Wordpress 插件的程序。

无论如何,这个概念是这段代码是子例程的一部分,它通过目录中的 .php 文件递归,并尝试对以“Version:”、“version:”、“*Version:”开头的文件进行模式匹配等从文件中,如果模式匹配,则另一个子尝试提取字符“:”后面的值以获取正确的版本号。

$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;
                }
            }
        }

问题是我似乎在逻辑上有错误,文件实际上匹配 " . phpversion() . "\n"; Version stored " 。 php版本()。 "\n" 用于搜索查询。以我有限的知识,我很难理解哪里出了问题,并且渴望得到一些建议。

下面提到的其他子类:

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;
}

如果我的子程序完全需要,我可以包含它。但是我的调试行显示了这一点:

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";

这似乎是错误所在。

【问题讨论】:

    标签: perl logic


    【解决方案1】:

    嗯,那里有很多冗余代码。如果您已经有了该行,为什么需要关闭文件并再次找到该行?您需要做的就是在找到该行时捕获该字符串:

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

    因此,通过使用/i 修饰符,您的匹配不区分大小写。通过将? 放在\*\s 之后,它们可以匹配0 次或1 次。通过使用(.*),该行的其余部分被捕获到$1

    您的正则表达式在最后一场比赛中缺少 ^ 行首锚点,我认为这是一个错字。如果没有,您可以简单地将正则表达式更改为/\bVersion:(.*)/i。而\b 仅对避免部分匹配有用,例如subversion: foo

    【讨论】:

    • * 是否意味着表达式仅在以 * 开头时才匹配?我想我必须对其进行修改以包含其他 OR 像 /^\s?Version:(.*)/
    • 我不知道“包括其他或喜欢”是什么意思,但不,\*? 的意思是“匹配文字 * 0 或 1 次”。您也可以使用[*\s]* 将所有此类字符设为可选。
    • @Droidzone 不......不是这样。 * 是可选的意味着它不必在那里......所以\*?\s?|\s? 意味着与\*?\s? 完全相同。
    • 例如,a?b? 将匹配abb,因此a?b?|b? 将是多余的。
    • 谢谢。但我承认我仍然很困惑。我的理解是这个表达式是从左到右读的。因此,在表达式/^\*?\s?Version:(.*)/ 中,它意味着查找以文字 * 开头的字符串,后跟 1 个或 0 个匹配的空格,然后是文字“Version:”,后跟任何字符的任何重复或零重复。我想我错了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多