您的整个匹配结果为'1/temperatoA,2/CelcieusB',因为它匹配以下表达式:
qr{ ( # begin group
\d+ # at least one digit
/ # followed by a slash
(\w+) # followed by at least one word characters
,? # maybe a comma
)* # ANY number of repetitions of this pattern.
}x;
'1/temperatoA,' 首先完成捕获#1,但是由于您要求引擎尽可能多地捕获这些,它会返回并发现该模式在'2/CelcieusB' 中重复(逗号不是必需的)。所以整场比赛就是你所说的那样,但你可能没想到的是'2/CelcieusB' 替换 '1/temperatoA,' 为$1,所以@987654328 @读取'2/CelcieusB'。
任何时候您想在特定字符串中捕获符合特定模式的任何内容,最好使用 global 标志并将捕获分配到一个数组中。由于数组不是像$1 这样的单个标量,它可以保存为捕获#1 捕获的所有值。
当我这样做时:
my $str = '1/temperatoA,2/CelcieusB!23/33/44,55/66/77';
my $regex = qr{(\d+/(\w+))};
if ( my @matches = $str =~ /$regex/g ) {
print Dumper( \@matches );
}
我明白了:
$VAR1 = [
'1/temperatoA',
'temperatoA',
'2/CelcieusB',
'CelcieusB',
'23/33',
'33',
'55/66',
'66'
];
现在,我认为这可能不是您所期望的。但是'3' 和'6' 是单词字符,所以——在斜线之后——它们符合表达式。
因此,如果这是一个问题,您可以将您的正则表达式更改为等效的:qr{(\d+/(\p{Alpha}\w*))},指定第一个字符必须是 alpha 后跟任意数量的单词字符。然后转储看起来像这样:
$VAR1 = [
'1/temperatoA',
'temperatoA',
'2/CelcieusB',
'CelcieusB'
];
如果您只需要'temperatoA' 或'CelcieusB',那么您捕获的内容超出了您的需要,并且您希望您的正则表达式为qr{\d+/(\p{Alpha}\w*)}。
但是,在捕获表达式中捕获多个块的秘诀是将匹配项分配给一个数组,然后您可以对数组进行排序以查看它是否包含您想要的数据。