【问题标题】:Pattern Matching in perlperl 中的模式匹配
【发布时间】:2013-07-08 19:18:03
【问题描述】:

我想从文件中解析一些信息。

文件中的信息:

Rita_bike_house_Sha9

Rita_bike_house

我想要像dis这样的输出

$a = Rita_bike_house and $b = Sha9,

$a = Rita_bike_house and $b = "original"

为了得到,我使用了以下代码:

$name = @_; # This @_ has all the information from the file that I have shown above. 

#For matching pattern Rita_bike_house_Sha9 
($a, $b) = $name =~  /\w\d+/; 

if ($a ne "" and $b ne "" ) { return ($a,$b) } 
# this statement doesnot work at all as its first condition 
# before the end is not satisified. 

有什么方法可以将“Rita_bike_house”存储在$a 和“Sha9”存储在$b?我认为我的正则表达式缺少某些东西。你有什么建议吗?

【问题讨论】:

  • $name = @_ 是代码异味。你的意思可能是($name)=@_
  • \w 也匹配_(下划线),所以你需要更精确的匹配规则。
  • 很抱歉。是的,它是 ($name) = @_;
  • 我厌倦了模式匹配为 /\w_\w_\w_([\w\d]+)/。但是,它不起作用。模式匹配中有什么建议吗?谢谢
  • \w 只匹配一个字母。您需要\w+ 来匹配一个或多个字母(一个单词)。但是\w 也与_ 匹配,所以如果这就是你的意思,你可能最好使用[a-z]

标签: perl


【解决方案1】:

请不要在代码中使用变量$a$b。有按排序使用的,会让你感到困惑。

试试:

while( my $line = <DATA> ){
  chomp $line;

  if( $line =~ m{ \A ( \w+ ) _ ( [^_]* \d [^_]* ) \z }msx ){
    my $first = $1;
    my $second = $2;
    print "\$a = $first and \$b = $second\n";
  }else{
    print "\$a = $line and \$b = \"original\"\n";
  }
}

__DATA__
Rita_bike_house_Sha9
Rita_bike_house

【讨论】:

    【解决方案2】:

    不是很好,但是下一个:

    use strict;
    use warnings;
    
    while(<DATA>) {
        chomp;
        next if /^\s*$/;
        my @parts = split(/_/);
        my $b = pop @parts if $parts[$#parts] =~ /\d/;
        $b //= '"original"';
        my $a = join('_', @parts);
        print "\$a = $a and \$b = $b,\n";
    }
    
    __DATA__
    Rita_bike_house_Sha9
    Rita_bike_house
    

    打印:

    $a = Rita_bike_house and $b = Sha9,
    $a = Rita_bike_house and $b = "original",
    

    【讨论】:

    • 感谢您的输入,但我收到一条错误消息,提示“my $b = pop @parts if $parts[$#parts] =~ /\d/;”我不能使用 5.014;
    • 任何建议为什么它不解析行“my $b = pop @parts if $parts[$#parts] =~ /\d/;”
    【解决方案3】:

    如果您确定所需的模式将始终类似于“Sha9”并且它会出现在最后,那么只需进行贪婪匹配......

    open FILE, "filename.txt" or die $!;
    my @data = <FILE>;
    close(<FILE>);
    #my $line = "Rita_bike_house_Sha9";
    foreach $line (@data)
    {
        chomp($line);
        if ($line =~ m/(.*?)(_([a-zA-Z]+[0-9]+))?$/)
        {
            $a = $1;
            $b = $3 ? $3 : "original";
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-23
      相关资源
      最近更新 更多