是否有 Python 的 re.findall/re.finditer(迭代正则表达式结果)的 Perl 等价物?

Posted

技术标签:

【中文标题】是否有 Python 的 re.findall/re.finditer(迭代正则表达式结果)的 Perl 等价物?【英文标题】:Is there a Perl equivalent of Python's re.findall/re.finditer (iterative regex results)? 【发布时间】:2010-10-02 20:09:48 【问题描述】:

在 Python 中编译的正则表达式模式 have a findall method 执行以下操作:

返回所有不重叠的匹配项 字符串中的模式,作为列表 字符串。字符串被扫描 从左到右,匹配是 按找到的顺序返回。如果一个或 更多的群体出现在 模式,返回组列表;这 将是一个元组列表,如果 模式有多个组。空的 匹配项包含在结果中 除非他们触及 另一场比赛。

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

提前致谢!

【问题讨论】:

【参考方案1】:

在您的比赛中使用/g 修饰符。来自perlop 手册:

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

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

【讨论】:

天啊——当然!我应该从 Vim 领域意识到这一点。【参考方案2】:

基于 Chris 的回复,将 //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 循环本身内完成。

【讨论】:

但是@matches = 'I had a sandwich for lunch' =~ m/([aeiou])([nrs])/g 呢?当然,您会得到一个扁平的阵列,但是您可以将其拼接成两个(在这种情况下)。 :-) 啊-嗯。 Perl 的美妙之处在于总有另一种方式!我很高兴我说,“可能是这样的”:)【参考方案3】:

不错的初学者参考,内容与@kyle的答案相似:Perl Tutorial: Using regular expressions

【讨论】:

以上是关于是否有 Python 的 re.findall/re.finditer(迭代正则表达式结果)的 Perl 等价物?的主要内容,如果未能解决你的问题,请参考以下文章

在 python re.findall 中使用多个标志

python正则表达式re.findall(r"\b\w+\b", s)中的r是啥意思?

python025

re 模块 025

python中使用正则

Python正则表达式之findall疑点