我有一个自定义数据格式,包含我需要解析的打开/关闭标记,例如:
<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中找到任何访问捕获的能力,而整个问题似乎方式更难。我在这里缺少什么?
答案 0 :(得分:2)
您不需要在Python中进行替换。使用script
或re.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'}