是否有 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 等价物?的主要内容,如果未能解决你的问题,请参考以下文章