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