我想首先匹配后面跟着“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" ;
}
}
答案 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