【问题标题】:Unable to use range operator to find the text matching from a file无法使用范围运算符从文件中查找匹配的文本
【发布时间】:2017-02-13 11:12:00
【问题描述】:

我无法在下面的程序中使用范围运算符来查找提供的 2 个文本的开头和结尾之间的文本,即 $kw1 和 $kw2。我正在从名为 oiutput.txt 的文件中读取 $kw1 和 @kw2在这个节目中。 有人可以帮忙说明为什么我的范围运算符没有给出我想要的 o/p 吗?

my $file = "output.txt";

my $kw1 = "Session Initiation Protocol (REGISTER)";
my $kw2 = "CSeq: 3 REGISTER";   

open(my $fh, '<', $file) or die $!;
my @content = <$fh>;

#print @content;

foreach (@content) {

#print $kw1;
#print $kw2;

if (/$kw1/ .. /$kw2/) {
    print "$_\n";
    }
}

我从 Is 搜索的示例数据:

CSeq: 3 REGISTER
Session Initiation Protocol (REGISTER)
                Temp
                Temp
                Session Initiation Protocol (REGISTER)
        Session Initiation Protocol (REGISTER)
CSeq: 2 REGISTER
CSeq: 1 REGISTER
CSeq: 0 REGISTER

【问题讨论】:

  • 转义\(REGISTER\)
  • 我仍然在 E:\Automation Related\Perl Scripts - ALL\IMS_debugging\test.pl 第 17 行收到 # Failed test 'data structure should be the same' # 失败。# Structures begin different at: # $got->{j} = '867-5309x' # $expected->{j} = '867-5309' # 看起来你没有通过 1 的 1 测试。
  • 可以处理一些您正在匹配的示例数据。
  • 另外:我不确定范围运算符在 foreach 循环中是否能正常工作。通常我会在while ( &lt;$fh&gt; ) { 内完成...
  • 添加了示例数据。用while循环也不例外。

标签: perl


【解决方案1】:

好的,我认为首先 - 你的问题是范围运算符是错误的方式,因为CSeq: 3 REGISTER 出现在文件中之前 Session Initiation Protocol \(REGISTER\)

但是你已经评论了一些测试结果:

1 不行 1 - 数据结构应该相同 # 失败的测试'数据结构应该相同' # 在 E:\Automation Related\Perl Scripts - ALL\IMS_debugging\test.pl 第 17 行。# 结构开始不同at: # $got->{j} = '867-5309x' # $expected->{j} = '867-5309' # 看起来你没有通过 1 的 1 次测试

这与您提供给我们的样本完全不符 - 数据中不存在数字,x 也不存在。

但无论如何,这确实有效:

#!/usr/bin/perl

use strict;
use warnings;
my $file = "output.txt";


my $kw1 = "Session Initiation Protocol (REGISTER)";
my $kw2 = "CSeq: 3 REGISTER";   

while (<DATA>) {

   if ( /\Q$kw2\E/ ... /\Q$kw1\E/ ) {
      print;
   }
}


__DATA__
CSeq: 3 REGISTER
Session Initiation Protocol (REGISTER)
                Temp
                Temp
                Session Initiation Protocol (REGISTER)
        Session Initiation Protocol (REGISTER)
CSeq: 2 REGISTER
CSeq: 1 REGISTER
CSeq: 0 REGISTER

您需要\Q \E,因为() 是一个正则表达式元字符。你可以改用quotemeta

如果您需要匹配“会话启动协议”的 second 实例,则匹配空格即可。

if ( /\Q$kw2\E/ ... /\s\Q$kw1\E/ ) 

【讨论】:

  • 谢谢@Sobrique。除了范围运算符之外,还有其他方法可以从文件中获取特定文本吗?
  • 我问这个是因为上面的程序只是根据 kw1 和 kw2 捕获数据,如果输入文件中存在多个 kw1 和 kw2 是否有任何控件可以抓取它们考虑到所有出现的 kw1 和 kw2 都具有相同的文本..
  • 会话启动协议 (REGISTER) 临时数据在这里 CSeq:3 注册发生-1 会话启动协议 (REGISTER) 临时数据在这里 CSeq:3 注册发生-2 会话启动协议 (REGISTER) 临时数据在这里 CSeq : 3 REGISTER 发生-3
  • 是的,但我可能会以完全不同的方式解决这个问题,所以我建议将其作为一个不同的问题发布。包括样本数据和期望的结果。
  • 好的,谢谢。我已经为此发布了另一个主题 - 如何从文本文件中按顺序或控制方式提取 2 个字符串之间的特定数据如果遇到多个这样的实例
【解决方案2】:

我相信这可能会,尚未测试,所以请匹配。

  use strict;
  use warnings;
  my $file = "output.txt";

  open(my $fh, '<', $file) or die $!;
  while ( <$fh> ) {

  if (/Session Initiation Protocol \(REGISTER\)/ .. /CSeq: 3 REGISTER/) {
      print "$_\n";
      }
  }

【讨论】:

  • 我收到错误...1..1 不正常 1 - 数据结构应该相同 # 失败的测试“数据结构应该相同”# 在 E:\Automation Related\Perl脚本 - ALL\IMS_debugging\test.pl 第 17 行。# 结构开始不同:# $got->{j} = '867-5309x' # $expected->{j} = '867-5309' # 看起来像你1 次测试失败。
  • 这段代码中没有x 可能来自哪里。您的测试正在做一些奇怪的事情。或者您的输入不是完全您所说的那样。
  • 我使用的是上面粘贴的相同输入。我认为 x 只不过是一些垃圾值。
  • 867-5309 也不会出现在输出中
  • 我又想这是一些垃圾值,因为它不在输入内。
猜你喜欢
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-03
相关资源
最近更新 更多