我正在读取一个文件,并在开头跟一个十六进制数的行匹配一个正则表达式,然后是几个点分隔的十六进制值,后跟可选的数组名,它可能包含一个选项索引。例如:
010c10 00000000.00000000.0000a000.02300000 myFooArray [0]
while (my $rdLine = <RDHANDLE>) {
chomp $rdLine;
if ($rdLine =~ m/^([0-9a-z]+)[ \t]+([0-9.a-z]+)[ \t]*([A-Za-z_0-9]*)\[*[0-9]*\]*$/) {
...
包含这些十六进制字符串的源文件也是脚本生成的。这种匹配适用于某些文件,但是当匹配条件中存在最后一个$时,通过完全相同的脚本生成的其他文件(即没有额外的空格,格式等)不匹配。 如果我将条件修改为没有结束$,则行按预期匹配。
另一个奇怪的事情就是调试它,我添加了一个这样的打印语句:
if ($rdLine =~ m/^([0-9a-z]+)[ \t]+/) {
print "Hey first part matched for $rdLine \n";
}
if ($rdLine =~ m/^([0-9a-z]+)[ \t]+([0-9.a-z]+)/) {
print "Hey second part matched for $rdLine \n";
}
以下输入的终端输出会占用第一个字符:
010000 00000000 foo
"ey first part matched for 010000 00000000 foo
ey second part matched for 010000 00000000 foo"
如果我删除了chomp,它会正确打印Hey,而不仅仅是ey。
任何线索都赞赏!
答案 0 :(得分:0)
&#34;通过完全相同的脚本生成的其他文件(即没有额外的空格,格式等)在匹配条件中出现最后$时不匹配&#34;
虽然你否认它,但我确信你的文件在行尾之前直接包含一个空格字符。您应该使用Data::Dump
进行检查以显示每个文件记录的真实内容。喜欢这个
use Data::Dump;
dd \$read_line;
最好使用
$read_line =~ s/\s+\z//;
取代chomp
。这将删除所有空格和制表符,以及每行末尾的回车符和换行符等行尾。
&#34;如果我删除了chomp,它会正确打印Hey而不仅仅是ey。&#34;
看起来您正在使用Linux计算机,处理在Windows平台上生成的文件。 Windows使用两个字符CR LF作为记录分隔符,而Linux仅使用LF,因此chomp
仅删除尾随LF,而CR会导致字符串的开头被覆盖。
如果您没有追踪空格的次要问题,那么此处的最佳解决方案是将chomp $read_line
替换为$read_line =~ s/\R\z//
。 \R
character class匹配换行符序列的Unicode概念,并在Perl 5的第10版中引入。但是,前面提到的s/\s+\z//
也会处理你的行结尾,应该是你所有的需要。
答案 1 :(得分:0)
鲍罗丁是对的,\ r \ n是罪魁祸首。
我使用了不太优雅的解决方案,但它确实有效:
$rdLine =~ s/\r//g;
接下来是:
chomp $rdLine;