изменение нескольких выражений в одной строке в perl - PullRequest
2 голосов
/ 09 декабря 2010

Я хочу взять строку, содержащую несколько выражений одной и той же структуры, содержащую 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 ]

2 голосов
/ 09 декабря 2010

Это то, что я использовал в конце:

$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 голос
/ 09 декабря 2010

Просто небольшая поправка, но оба ваших регулярных выражения не делают то, что вы думаете.

/[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 обычно создают довольно сложный для понимания код.Все пробелы необязательны, так что раздавите их для однострочника!

1 голос
/ 09 декабря 2010

Ваше регулярное выражение, кажется, работает хорошо для меня, за исключением случаев, когда число гекса отсутствует в хэше.

Я пытался:

#!/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, которые не являются ключами в хэше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...