我有一个字符串1/temperatoA,2/CelcieusB!23/33/44,55/66/77
,我想提取单词temperatoA
和CelcieusB
。
我有这个正则表达式(\d+/(\w+),?)*!
,但是我只得到匹配的1/temperatoA,2/CelcieusB!
为什么?
最佳答案
您的整个匹配结果为'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
,因此$1
读取'2/CelcieusB'
。每当您要捕获适合特定模式的特定字符串时,总是最好使用 g lobal标志并将捕获分配到数组中。由于数组不是像
$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*))}
,指定第一个字符必须为字母,后跟任意数量的单词字符。然后转储如下所示:$VAR1 = [
'1/temperatoA',
'temperatoA',
'2/CelcieusB',
'CelcieusB'
];
而且,如果只希望
'temperatoA'
或'CelcieusB'
,那么您捕获的内容将超出您的需要,并且您希望正则表达式为qr{\d+/(\p{Alpha}\w*)}
。但是,在捕获表达式中捕获多个块的 secret 是将匹配项分配给数组,然后可以对数组进行排序以查看其是否包含所需的数据。