Regex 如何从特定行读取到另一行-Perl

Regex 如何从特定行读取到另一行-Perl,regex,perl,readline,Regex,Perl,Readline,我正在做一个Perl脚本,我有一个日志文件,需要从中提取数据。我想知道如何从一行读到另一行(不是文件的末尾) 我试着这样做,如果它到达我想停的那一行,但它不起作用,我就把放在最后一个if。我想开始读的那行是,停在。我这样做是因为我的正则表达式捕获了我不需要的数据,所以我尝试从一行读取到另一行 这就是我到目前为止所做的: while(<$log_fh>) { if($. =~ /\<TEST_HEAD TH 1\>/) { if ( /Compu

我正在做一个Perl脚本,我有一个日志文件,需要从中提取数据。我想知道如何从一行读到另一行(不是文件的末尾)

我试着这样做,如果它到达我想停的那一行,但它不起作用,我就把
放在最后一个if
。我想开始读的那行是
,停在
。我这样做是因为我的正则表达式捕获了我不需要的数据,所以我尝试从一行读取到另一行

这就是我到目前为止所做的:

while(<$log_fh>)
{
    if($. =~ /\<TEST_HEAD TH 1\>/)
    {
      if ( /Computer Name:\s*(\S+)(-\d+)/i )
      {
          $details{tester_name} = $1 . $2;
          $details{tester_type} = $1;
          push @{$details{tester_arr}}, $1 . $2;
      }
      elsif ( /Operating System:\s*(.*\S)/i )
      {
          $details{op_sys} = $1;
      }
      elsif ( /IG-XL Version:\s*([^;]*)/i )
      {
          $details{igxl_vn} = $1;
      }
      elsif ( /^([\d]+)\.\d\s+(\S+)\s+([\d-]*)\s+([\d|\w]*)(?=\s)/ )
      {
          push @{$details{slot}}, $1;
          push @{$details{board_name}},  $2;
          push @{$details{part_no}},  $3;
          push @{$details{serial_no}},  $4;
      }
      last if $. == /\<\/TEST_HEAD TH 1\>/;
    }
}
while()
{
如果($。=~/\/)
{
如果(/计算机名:\s*(\s+)(\d+)/i)
{
$details{tester_name}=$1.$2;
$details{tester_type}=$1;
推送{$details{tester_arr}},$1.$2;
}
elsif(/操作系统:\s*(.*\s)/i)
{
$details{op_sys}=$1;
}
elsif(/IG-XL版本:\s*([^;]*)/i)
{
$details{igxl_vn}=$1;
}
elsif(/^([\d]+)\。\d\s+(\s+)\s+([\d-]*)\s+([\d |\w]*)(?=\s)/)
{
推送{$details{slot}}$1;
推送{$details{board_name}},$2;
推送{$details{part_no}},$3;
推送{$details{serial_no},$4;
}
最后一个if$.=/\/;
}
}
只是原始数据文件的一个修改示例:

<TEST_HEAD TH 1> #Start reading here

    (Lines containing data to be captured)

</TEST_HEAD TH 1> #end reading here
#从这里开始阅读
(包含要捕获的数据的行)
#到此为止

在不深入嵌套匹配逻辑的情况下,您可能需要更改

if($. =~ /\<TEST_HEAD TH 1\>/)
if($.=~/\/)
进入

if(///../)

您所问的实际上是XY问题,最好使用xml解析器处理类似xml的文档

在不具体了解数据外观的情况下,我还提供了另一种方法

$/
设置为记录分隔符,然后一次性抓取一块文本。然后,您可以同时对其应用一组不同的正则表达式

例如:

local$/='TEST_HEAD';
而(){
下一个,除非m/^\s*TH/;
我的($tester\u name,$tester\u id)=(m/计算机名:\s*(\s+)(-\d+)/i);
my($op_sys)=(m/操作系统:\s*(.*\s)/i);
我的($slot、$board、$part、$serial)=
(m/^([\d]+)\.\d\s+(\s+)\s+([\d-]*)\s+([\d\w]*)(?=\s)/m);
#等等。
#然后验证并更新阵列:
$details{$tester\u name}=$tester\u name;
##等等。
}

$。
=>当前文件行号@Саа27哦,我刚刚看到了链接。如果我想停在那一行,我应该使用什么?这看起来像XML。是吗?如果是这样的话,解决方案可能是平衡的easier@Sobrique不是,我找到了解决办法。我删除了
if
条件并添加了
last if/^\/
位于最后一个
elsif
的末尾,位于花括号后。你认为如果我在后面加上另一个包含另一个正则表达式的
if
条件,是否有可能?因为我还想读另一行中的几行。或者我应该为
创建一个新的while循环吗?@ССц27输入文件有多大?(例如,小于200KB)对于小文件,最简单的选择可能是将整个文件压缩成变量,并从标量变量中提取记录。嗯,但只有这两行(可能还有一些太多的行需要指出)是该格式,其余的是纯文本。整个文件会被视为类似XML的文档吗?对于嵌套逻辑来说,这没关系,这只是为了捕获我想要的行上的数据。我尝试了你的答案,它给了我一个
在串联(.)中使用未初始化值$或在…
if (/<TEST_HEAD TH 1>/ .. /<\/TEST_HEAD TH 1>/)
local $/ = 'TEST_HEAD';

while (<$log_fh>) {
    next unless m/^\s*TH/;

    my ( $tester_name, $tester_id ) = (m/Computer Name:\s*(\S+)(-\d+)/i);
    my ($op_sys) = (m/Operating System:\s*(.*\S)/i);
    my ( $slot, $board, $part, $serial ) =
        (m/^([\d]+)\.\d\s+(\S+)\s+([\d-]*)\s+([\d|\w]*)(?=\s)/m);

    # etc.

    # then validate and update your array:
    $details{$tester_name} = $tester_name;
    ## etc.
}