Как я могу выполнить итерации по переменным соответствия регулярного выражения в Perl?

У меня есть долгое регулярное выражение, которое анализирует текстовый файл в различные переменные соответствия.

Для устойчивости переменные соответствия, вероятно, будут содержать пробел. Я хотел бы удалить пробел систематическим способом путем итерации по переменным соответствия.

Например, у меня есть переменные соответствия $2 через $14 это содержит некоторый пробел.

Я мог сделать:

my @columns = my ($serNum, $helixID, $initResName, $initChainID,
$initSeqNum, $initIcode, $endResName, $endChainID, $endSeqNum,
$endICode, $helixClass, $comment, $length) = 
($2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);

### Remove whitespace                       
foreach my $element (0..$#columns) {
    $columns[$element] =~ s/^\s+//;
    $columns[$element] =~ s/\s+$//;
}

Но это только удаляет пробел в элементах в @column, и оставляет правильно именованные скаляры, $serNum, $helixID, и т.д., нетронутый.

Существует ли способ удалить пробел в каждой из переменных соответствия, прежде чем я скопирую их в более хорошо названные скаляры, или существует ли способ выполнить итерации по этим хорошо названным скалярам самим и удалить пробел оттуда?

Я предполагаю, что мог бы быть некоторый способ сделать это со ссылками.

5
задан EMiller 30 June 2010 в 15:21
поделиться

2 ответа

Вы можете сначала хранить переменные соответствия в массиве, а затем удалять пробелы с помощью map:

my @matches = ($2, $3, $4, ...);

my ($serNum, $helixID, ...) 
  = map { (my $v = $_) =~ s/^\s+|\s+$//g; $v } @matches;
4
ответ дан 14 December 2019 в 08:40
поделиться

Приятно видеть хороший уровень детализации в вопросах! Это позволяет сообществу гораздо лучше решить проблему.

Что бы я сделал, так это перешел от массива элементов с «хорошо названным» к хешу. Это чище и может уменьшить количество переменных, необходимых в коде.

my @matches = $data =~ m{$regex};   # Populates @matches with ( $1, $2, $3, ..)
my @labels  = qw/serNum helixID initResName .../;   # Create labels

my %record;                                 # Initialize hash
@record{@labels} = grep { s!^\s*|\s*$!!g }  # Strips out leading/trailing spaces
                   @matches[1..$#matches];  # Populate %record with array slice
                                            # Array slice of @matches needed to 
                                            # ignore the $1

# Now data can be accessed as follows:
print $record{helixID};                     # Prints the helix ID in the record

Часть grep , возможно, потребует некоторых пояснений. Это интересный способ избежать лексического копирования каждой строки внутри вызова map .

По своей природе grep фильтрует массивы. Вот почему регулярное выражение с удалением пробелов пришлось изменить с \ s + на \ s * , чтобы регулярное выражение всегда совпадало и никакие элементы не отфильтровывались.

3
ответ дан 14 December 2019 в 08:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: