ana*_*nsi 10 python regex perl
在Perl中,我会做这样的事情,在regexp中使用不同的字段,用()分隔不同的字段并使用$获取它们
foreach $line (@lines)
{
$line =~ m/(.*?):([^-]*)-(.*)/;
$field_1 = $1
$field_2 = $2
$field_3 = $3
}
Run Code Online (Sandbox Code Playgroud)
我怎么能在Python中做这样的事情?
Ale*_*lli 19
您的代码段的"Canonical"Python翻译...:
import re
myre = re.compile(r'(.*?):([^-]*)-(.*)')
for line in lines:
mo = myre.search(line)
field_1, field_2, field_3 = mo.groups()
Run Code Online (Sandbox Code Playgroud)
导入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()
Run Code Online (Sandbox Code Playgroud)
fri*_*edo 13
在Perl中,使用数组比使用数字后缀一堆标量要好得多.例如
foreach my $line ( @lines ) {
my @matches = ( $line =~ m/(.*?):([^-]*)-(.*)/ );
...
}
Run Code Online (Sandbox Code Playgroud)
在Python中,re
模块返回包含捕获组信息的匹配对象.所以你可以写:
match = re.search( '(.*?):([^-]*)-(.*)', line )
Run Code Online (Sandbox Code Playgroud)
那么你的比赛将是可用的match.group(1)
,match.group(2)
等等.
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)
Run Code Online (Sandbox Code Playgroud)
并且不要忘记在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')]
Run Code Online (Sandbox Code Playgroud)
正如另一个例子,python为命名捕获组提供了非常好的支持(事实上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'}
Run Code Online (Sandbox Code Playgroud)
这是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()
Run Code Online (Sandbox Code Playgroud)
现在all_the_fields
是具有对应于捕获组名称("field1","field2"和"field3")的键的字典以及对应于各个捕获组的内容的值.
为什么你应该更喜欢命名捕获组
>>> 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'
Run Code Online (Sandbox Code Playgroud)
一些好的正则表达式资源: