在Perl中,我会做这样的事情,在regexp中使用不同的字段,用()分隔不同的字段并使用$
获取它们foreach $line (@lines)
{
$line =~ m/(.*?):([^-]*)-(.*)/;
$field_1 = $1
$field_2 = $2
$field_3 = $3
}
我怎么能在Python中做这样的事情?
答案 0 :(得分:18)
你的代码段的“Canonical”Python翻译......:
import re
myre = re.compile(r'(.*?):([^-]*)-(.*)')
for line in lines:
mo = myre.search(line)
field_1, field_2, field_3 = mo.groups()
导入re
是必须的(导入通常在模块的顶部完成,但这不是强制性的)。预编译RE是可选的(如果您使用re.search
函数,它将动态编译您的模式)但建议(因此您不依赖编译的RE对象的模块缓存来提高性能,还为了拥有一个RE对象并调用它的方法,这在Python中更为常见。
您可以使用match
方法(从一开始就尝试匹配,无论您的模式是否以'^'
开头)或search
方法(尝试在任何地方进行匹配) ;用你给定的模式它们应该是等价的(但我不是100%肯定)。
.groups()
方法返回所有匹配的组,因此您可以将它们全部分配到一个gulp(使用Python中的列表,就像在Perl中使用数组一样,可能更正常,但是因为您选择使用Perl中的标量你也可以用Python做同样的事情。)
如果任何行与RE不匹配,这将失败,如果你知道它们都匹配,那就没问题了(我不确定你的Perl的行为是什么,但我认为它会“重用”以前的相反,匹配线的值,这是奇特的......除非,你知道所有的线匹配;-)。如果您只想跳过不匹配的行,请将最后一个语句更改为以下两个:
if mo:
field_1, field_2, field_3 = mo.groups()
答案 1 :(得分:12)
在Perl中,使用数组比使用数字后缀一堆标量要好得多。 E.g。
foreach my $line ( @lines ) {
my @matches = ( $line =~ m/(.*?):([^-]*)-(.*)/ );
...
}
在Python中,re
模块返回包含捕获组信息的匹配对象。所以你可以写:
match = re.search( '(.*?):([^-]*)-(.*)', line )
然后您的匹配将在match.group(1)
,match.group(2)
等
答案 2 :(得分:8)
Python支持使用re
模块的正则表达式。 re.search()
方法返回MatchObject
,其中包含group()
等方法,可用于检索“捕获组”信息。
例如:
m = re.search(r'(.*?):([^-]*)-(.*)', line)
field_1 = m.group(1)
field_2 = m.group(2)
field_3 = m.group(3)
答案 3 :(得分:6)
不要忘记在Python中,TIMTOWTDI;)
import re
p = re.compile(r'(\d+)\.(\d+)')
num_parts = p.findall('11.22 333.444') # List of tuples.
print num_parts # [('11', '22'), ('333', '444')]
答案 4 :(得分:5)
正如另一个例子,python为named capture groups提供了非常好的支持(事实上python开创了对命名捕获组的支持)。
要使用命名捕获组,只需在捕获组的左括号内添加?P<the_name_of_the_group>
即可。
这使您可以非常轻松地在字典中获取所有匹配项:
>>> import re
>>> x = re.search("name: (?P<name>\w+) age: (?P<age>\d+)", "name: Bob age: 20")
>>> x.groupdict()
{'age': '20', 'name': 'Bob'}
以下是OP的示例,已修改为使用命名捕获组
import re
find_fields_regex = re.compile(r'(?P<field1>.*?):(?P<field2>[^-]*)-(?P<field3>.*)')
for line in lines:
search_result = find_fields_regex.search(line)
all_the_fields = search_result.groupdict()
现在all_the_fields
是一个字典,其中的键对应于捕获组名称(&#34; field1&#34;,&#34; field2&#34;和&#34; field3&#34;)和对应于各个捕获组的内容的值。
为什么您应该更喜欢命名捕获组
>>> import re
>>> x = re.search("name: (?P<name>\w+) age: (?P<age>\d+)", "name: Bob age: 20")
>>> x.groupdict()
{'age': '20', 'name': 'Bob'}
>>> x.group(1)
'Bob'
>>> x.group(2)
'20'
一些优秀的正则表达式资源: