如何在Perl中迭代正则表达式匹配变量?

时间:2010-06-29 19:05:21

标签: regex perl reference

我有一个很长的正则表达式,可以将文本文件解析为各种匹配变量。

对于稳健性,匹配变量可能包含空格。我想通过迭代匹配变量以系统的方式删除空格。

例如,我的匹配变量$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 个答案:

答案 0 :(得分:4)

您可以先将匹配变量存储在数组中,然后使用map:

删除空格
my @matches = ($2, $3, $4, ...);

my ($serNum, $helixID, ...) 
  = map { (my $v = $_) =~ s/^\s+|\s+$//g; $v } @matches;

答案 1 :(得分:3)

看到问题的详细程度令人耳目一新!它使社区能够以更好的方式解决问题。

我要做的是从'命名'的元素数组迁移到哈希。这更清晰,有可能减少代码中所需的变量数量。

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*,以确保正则表达式始终匹配,因此不会过滤掉任何项目。