简体   繁体   English

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

[英]changing several expressions in one line in perl

I want to take a line containing several expressions of the same structure, containing 4 digit hexa numbers, and changing the number in that structure according to a hash table. 我想一行包含相同结构的几个表达式,包含4位六进制数字,并根据哈希表更改该结构中的数字。 I tried using this next peace of code: 我尝试使用下面的代码:

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){};

Where $hash_point is a pointer to the hash table. 其中$hash_point是指向哈希表的指针。

But it tells me that I try to use an undefined value, when I tried running the fallowing code: 但是它告诉我,当我尝试运行休闲代码时,我尝试使用未定义的值:

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";};

It changed all the wanted numbers to "----" but printed out the values only 2 times (there were much more changes). 它将所有想要的数字都更改为“ ----”,但仅将值打印了2次(变化更多)。

Where is the problem? 问题出在哪儿?

This is what I used in the end: 这是我最后使用的:

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

and in order to account for numbers not in the hash I've added: 为了计算不在哈希表中的数字,我添加了:

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

I also wanted to know what numbers don't appear at the hash: 我还想知道什么数字不会出现在哈希表中:

$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;

and finaly, I wanted to be able to control whether the massage from the previous stage would be printed, I've added the use of $flag which in defined only if I want the massages to appear: 最后,我希望能够控制是否可以打印前一阶段的消息,我添加了$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;

Your regexp seems to work well for me except when hexa number is not present in the hash. 您的正则表达式似乎对我来说很好用,除非哈希中不存在六进制数。

I tried: 我试过了:

#!/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;

This produces: 这将产生:

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

The errors are for numbers ab88 and cdef that are not keys in the hash. 错误是由于数字ab88cdef而不是哈希中的键。

Just a small correction, but both of your regexes don't do what you think it does. 只是一个小的更正,但是您的两个正则表达式都没有执行您认为的操作。

/[a-f,0-9]/

Matches any character from a to f, 0 to 9, and a comma. 匹配从a到f,0到9 以及逗号的任何字符 You are looking for 你在找

/[a-z0-9]/

Not that this is what is breaking your program (M42 probably got it right, but we can't be sure unless you show us the hash). 并不是说这是在破坏您的程序(M42可能正确了,但是除非您向我们显示哈希值,否则我们无法确定)。

Also, apologies, not enough rep to actually answer to other posts. 另外,很抱歉,没有足够的代表实际回答其他帖子。

EDIT: Well, you go through a lot of hoops in that answer, so here's how I'd do it instead: 编辑:嗯,您在该答案中遇到了很多麻烦,所以这是我的替代方法:

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

Mainly because chaining and's and &&'s and sosuch generally makes for fairly hard-to-understand code. 主要是因为链接和的&&&的soso通常使得相当难以理解的代码成为可能。 All whitespace is optional, so squash it for the one-liner! 所有空格都是可选的,所以将其压缩为一排即可!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM