在perl中改变一行中的几个表达式

时间:2010-12-09 09:20:39

标签: regex perl

我想取一行包含几个相同结构的表达式,包含4位六进制数,并根据哈希表更改该结构中的数字。我尝试使用下一代代码:

while ($line =~ s/14'h([0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f])/14'h$hash_point->{$1}/g){};

其中$hash_point是指向哈希表的指针。

但它告诉我,当我尝试运行以下代码时,我尝试使用未定义的值:

while ($line =~ s/14'h([0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f])/14'h----/g){print $1," -> ",$hash_point->{$1},"\n";};

它将所有想要的数字更改为“----”,但只打印了2次值(更多的更改)。

问题出在哪里?

3 个答案:

答案 0 :(得分:2)

这是我最后使用的:

$line =~ s/14'h([0-9a-f][0-9a-f][0-9a-f][0-9a-f])/"14'h".$hash_point->{$1}/ge;

并且为了说明我添加的哈希值中没有的数字:

$line =~ s/14'h([0-9a-f][0-9a-f][0-9a-f][0-9a-f])/"14'h".((hash_point->{$1}) or ($1))/ge;

我还想知道散列中没有出现的数字:

$line =~ s/14'h([0-9a-f][0-9a-f][0-9a-f][0-9a-f])/"14'h".(($hash_point->{$1}) or (print "number $1 didn't change\n") &&($1))/ge;

最后,我希望能够控制是否打印前一阶段的按摩,我已经添加$flag的使用,只有在我想要按摩时才会出现:

$line =~ s/14'h([0-9a-f][0-9a-f][0-9a-f][0-9a-f])/"14'h".(($hash_point->{$1}) or (((defined($flag)) && (print "number $1 didn't change\n")) or ($1)))/ge;

答案 1 :(得分:1)

你的正则表达式似乎对我有用,除非哈希中没有六进制数。

我试过了:

#!/usr/bin/perl
use 5.10.1;
use strict;
use warnings;
use Data::Dumper;

my $line = q!14'hab63xx14'hab88xx14'hab64xx14'hab65xx14'hcdef!;
my $hash_point = {
ab63 => 'ONE',
ab64 => 'TWO',
ab65 => 'THREE',
};


while ($line =~ s/14'h([0-9,a-f][0-9,a-f][0-9,a-f][0-9,a-f])/14'h$hash_point->{$1}/g){};

say $line;

这会产生:

Use of uninitialized value in concatenation (.) or string at C:\tests\perl\test5.pl line 15.
Use of uninitialized value in concatenation (.) or string at C:\tests\perl\test5.pl line 15.
14'hONExx14'hxx14'hTWOxx14'hTHREExx14'h

错误适用于数字ab88cdef,它们不是哈希中的键。

答案 2 :(得分:1)

只是一个小小的修正,但你的两个正则表达都没有按照你的想法做到。

/[a-f,0-9]/

匹配a到f,0到9,和逗号中的任何字符。您正在寻找

/[a-z0-9]/

这不是破坏你的程序的原因(M42可能是正确的,但除非你向我们展示哈希,否则我们无法确定。)

此外,道歉,没有足够的代表实际回答其他帖子。

编辑: 好吧,你在那个答案中经历了很多箍,所以这就是我要做的事情:

s/14'h\K(\p{AHex}{4})/if (defined($hash_point->{$1})) {
                          $hash_point->{$1};
                      } else {
                          say $1 if $flag;
                          $1;
                      }/ge

主要是因为链接和&&和sosuch通常会产生相当难以理解的代码。所有的空白都是可选的,所以将它压成一行!