6

在 Python 中编译的正则表达式模式有一个findall方法可以执行以下操作:

返回字符串中模式的所有非重叠匹配,作为字符串列表。从左到右扫描字符串,并按找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。空匹配包含在结果中,除非它们触及另一个匹配的开始。

在 Perl 中执行此操作的规范方法是什么?我能想到的一个天真的算法是“当搜索并用空字符串替换成功时,执行 [suite]”。我希望有更好的方法。:-)

提前致谢!

4

3 回答 3

13

在比赛中使用/g修饰符。从perlop手册:

" /g" 修饰符指定全局模式匹配——即在字符串中匹配尽可能多的次数。它的行为方式取决于上下文。在列表上下文中,它返回与正则表达式中的任何捕获括号匹配的子字符串列表。如果没有括号,则返回所有匹配字符串的列表,就好像整个模式都有括号一样。

在标量上下文中,每次执行 " m//g" 都会找到下一个匹配项,如果匹配则返回 true,如果没有进一步匹配则返回 false。可以使用该pos()函数读取或设置最后一次匹配后的位置;见“ pos”中perlfunc。失败的匹配通常会将搜索位置重置为字符串的开头,但您可以通过添加“ /c”修饰符(例如“ m//gc”)来避免这种情况。修改目标字符串也会重置搜索位置。

于 2009-01-22T02:04:14.110 回答
8

//g为了建立克里斯的回应,将正则表达式封装在一个while循环中可能最相关,例如:

my @matches;
while ( 'foobarbaz' =~ m/([aeiou])/g )
{
    push @matches, $1;
}

粘贴一些快速的 Python I/O:

>>> import re
>>> re.findall(r'([aeiou])([nrs])','I had a sandwich for lunch')
[('a', 'n'), ('o', 'r'), ('u', 'n')]

为了在 Perl 中获得类似的东西,构造可能是这样的:

my $matches = [];
while ( 'I had a sandwich for lunch' =~ m/([aeiou])([nrs])/g )
{
    push @$matches, [$1,$2];
}

但总的来说,无论您要迭代什么功能,您都可以在while循环本身内完成。

于 2009-01-22T02:35:09.837 回答
2

不错的初学者参考,内容与@kyle的答案类似:Perl 教程:使用正则表达式

于 2009-01-22T02:36:28.070 回答