如何在python中进行正则表达式替换*和*捕获?

时间:2016-07-26 19:05:47

标签: python regex

我有一个自定义数据格式,包含我需要解析的打开/关闭标记,例如:

<t1>  15  </t1>  <t2>  25  </t2>

标签永远不会嵌套,但我事先并不知道标签名称。我不能指望符合XML的数据(例如,可能有&#34;&lt;&#34;或&#34;&gt;&#34;标签之间的字符),所以我不能使用普通的XML解析器。我可以假设关闭标签始终存在,并且同一文件中没有重复的标签。

我是一个perl家伙,但我需要在python中编写这个解析器。在perl中执行此操作的最简单方法是从前面进行替换,将下一个打开/关闭标记及其中的所有内容拉出,然后捕获替换的文本:

****************************************
#! /usr/bin/perl -w
%tags = ();
$_ = "<t1>  15  </t1>  <t2>  25  </t2>";

#              <   t1      >       15        <  /  t1  >  
while ( s| \s* <  ([^>]+)  >  \s* (.+\S) \s* <  /  \1  >  ||x ) {
    $tags{$1} = $2;
}

print "$_: $tags{$_}\n" for sort keys(%tags);

****************************************

在使用re.sub()之后,我无法在vanilla Python中找到任何访问捕获的能力,而整个问题似乎方式更难。我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

您不需要在Python中进行替换。使用scriptre.findall(),如下所示:

re.finditer()

import re with open('input.txt') as input_file: data = input_file.read() tags = {} for match in re.finditer(r'<\s*(.*?)\s*>\s*(.*?)\s*</\1>', data): tags[match.group(1)] = match.group(2) print tags 循环可以替换为dict理解。以下等同于我上面所写的内容。

for

答案 1 :(得分:0)

设置(我保留了你的正则表达式但是在字符串中加了几个字,所以我们可以看到替换实际上有效):

>>> import re
>>> s = 'front <t1>  15  </t1> middle <t2>  25  </t2> back'
>>> p = r'\s* <  ([^>]+)  >  \s* (.+\S) \s* <  /  \1  >'

如果您不介意双重扫描,可以先运行re.findall进行捕获,然后再运行re.sub进行替换。

>>> dict(re.findall(p, s, re.X))
{'t1': '15', 't2': '25'}

>>> re.sub(p, '', s, flags=re.X)
'before between after'

或者使用替换功能,例如:

>>> d = {}
>>> re.sub(p, lambda m: d.update([m.groups()]) or '', s, flags=re.X)
'before between after'

>>> d
{'t1': '15', 't2': '25'}