Как я могу перебрать переменные соответствия регулярного выражения в Perl? - PullRequest
5 голосов
/ 29 июня 2010

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

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

Например, у меня есть переменные соответствия от $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 и т. Д.

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

Полагаю, может быть какой-то способ сделать это со ссылками.

Ответы [ 2 ]

4 голосов
/ 29 июня 2010

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

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

my ($serNum, $helixID, ...) 
  = map { (my $v = $_) =~ s/^\s+|\s+$//g; $v } @matches;
3 голосов
/ 30 июня 2010

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

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

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*, чтобы обеспечить постоянство соответствия регулярному выражению, чтобы элементы не отфильтровывались.

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