Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
172 views
in Technique[技术] by (71.8m points)

regex - Print the matched string using perl

I want to match the string which is followed by " ETN : " i.e., (name1/name2 ) first and after I match it, I want to print the first occurrence of it before the string "data reached"

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)

Output :

name1/name2/ZN                  (abcLVT)

name3/name4/ZN                 (fhLVT)

CODE:

I tried to march the string first with ETN and tried to print it.

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

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

    $a = $names[3];

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

        { 
            print " $line 
" ; 
        }       

    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your code doesn't show the loop where you retrieve $line from the file but it looks like you're trying to use a nested approach, in which case you're missing another such loop. That would work if each record ends in "data reached", but that's not consistently present in your example data. However a nested loop isn't necessary in this case nor does it add to readability, so just use a single loop as shown below.

First, a few comments:

  • You don't need the m// for your regex as // will suffice since it's not a multi-line match.

  • You should use an ^ anchor not only for accuracy but speed.

  • You can retrieve the name from the regex without the split line you have by using the special match variables e.g. $1 as shown below.

  • I didn't use $line in my code below, just the assumed $_ var, which is common perl style. Since it's assumed, it wasn't written in the code.

  • If you don't chomp the line, you don't need to add a newline when printing.

Here's your code, with the input loop shown, modified to work. I used $name in two conditionals below, which is equivalent to checking if it is both defined and not empty.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...