Regex 在perl中更改一行中的多个表达式
我想取一行,其中包含几个相同结构的表达式,包含4位十六进制数字,并根据哈希表更改该结构中的数字。我尝试使用下一代代码:Regex 在perl中更改一行中的多个表达式,regex,perl,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
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次值(有更多的变化)
问题出在哪里?您的regexp对我来说似乎工作得很好,除非哈希中没有十六进制数 我试过:
#!/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
错误是针对不是散列中的键的数字
ab88
和cdef
。只是一个小的更正,但两个正则表达式都没有做您认为它做的事情
/[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
主要是因为链接和&&&s以及SOSO通常会导致相当难理解的代码。所有空格都是可选的,所以请将其压缩为一行 这就是我最后使用的:
$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;
这看起来是正确的解决方案。我删除了我自己的答案。