使用perl打印匹配的字符串

时间:2015-09-04 18:07:04

标签: regex perl

我想首先匹配后面跟着“ETN:”的字符串,即(name1 / name2),在匹配之后,我想在字符串“data reach”之前打印它的第一个匹配项

ETN: name1/name2  

   abchsfk/jshflka/ZN                       (cellLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name1/name2/ZN                 (abcLVT)    

   data reached



   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name1/name2/ZN                  (abcLVT)

ETN: name3/name4  

   abchsfk/jshflka/ZN                       (cellLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name3/name4/ZN                 (fhLVT)    

   data reached



   asjhfdjkfd/sjfdskjfhdk/hsakfshf/Z        (celLVT)

   asjkfsa/sfklfkshfsf/Z                    (mobSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   asjhdjs/jhskjds/ZN                       (abcSVT)

   shdsjk/jhskd/ZN                          (xyzSVT)

   name3/name4/ZN                  (fhLVT)

输出:

name1/name2/ZN                  (abcLVT)

name3/name4/ZN                 (fhLVT)

CODE:

我试图先用ETN对字符串进行游行并尝试打印它。

if ($line =~ m/ETN: /)

        { 
    my @names = split / /, $line;

    $a = $names[3];

        if ($line =~ m /$a  /)

        { 
            print " $line \n" ; 
        }       

    }

2 个答案:

答案 0 :(得分:1)

您的代码没有显示从文件中检索$ line的循环,但看起来您正在尝试使用嵌套方法,在这种情况下,您将错过另一个此类循环。如果每个记录以"数据到达"结束,那将起作用,但在示例数据中并不一致。但是,在这种情况下,嵌套循环不是必需的,也不会增加可读性,因此只需使用单个循环,如下所示。

首先,一些评论:

  • 你不需要m //为你的正则表达式//就足够了,因为它不是多行匹配。

  • 你应该使用^锚不仅是为了准确而是为了速度。

  • 您可以使用特殊匹配变量从正则表达式中检索名称而不使用分割线。 $ 1,如下所示。

  • 我在下面的代码中没有使用$ line,只是假定的$ _ var,这是常见的perl风格。由于它被假定,它没有写在代码中。

  • 如果您没有选择该行,则不需要在打印时添加换行符。

这是您的代码,显示输入循环,修改后即可工作。我在下面的两个条件中使用了$ name,这相当于检查它是否已定义且不为空。

my $name;
while (<$in>)
{
    if (/^ETN:\s+(\S+)/) { $name = $1 }
    elsif ( $name and /^\s+$name/) { print }
}  
$name or warn("No ETN records found\n");

答案 1 :(得分:-1)

您可以使用简单的正则表达式。请尝试以下代码:

if ($inputstring =~ m/ENT:.*?($name1/$name2)ZN/) {
    print "$1\t$2"
}

$name1$name2将是匹配的字符串。这将打印:

name1 tab name2