我很难理解这个正则表达式的东西......
我有一个这样的字符串:
<wn20schema:NounSynset rdf:about="&dn;synset-56242" rdfs:label="{saddelmageri_1}">
我想使用findall()和groups来获取:
['56242','saddelmageri']
我可以将数字与“synset- [0-9]”和“{(。*?)}”之类的单词匹配,但如何编写它以获得上述结果?
这是一个后续问题 - 有些行看起来像这样:
<wn20schema:NounSynset rdf:about="&dn;synset-2589" rdfs:label="**{cykel_3: trehjulet cykel; tricykel,1_1}**">
在这种情况下,我想在{}之间提取这个结果:
['2589', ['cykel', 'trehjulet cykel', 'tricykel']]
这样我以后就可以把它作为一个键(2589)放入字典中:value(['cykel','trehjulet cykel','tricykel'])对。
有什么想法吗?
答案 0 :(得分:2)
请参阅this question的最佳答案。用正则表达式解析xml通常是一个糟糕的主意。 XML解析器是为此目的而构建的。
最快的方法可能是python的built-in minidom
答案 1 :(得分:1)
由于这似乎是xml数据,因此最好使用xml解析器,因为使用正则表达式解析xml非常非常难以正确执行。
但是,因为你特意要求正则表达式......
您的规格有点不精确,使用正则表达式时,您需要非常精确地确定匹配的内容。例如,rdfs:label值是否始终具有要剥离的_1?是否每行只有一个这样的数据块,或每行多个?此外,结果的顺序是否重要?
这是一个快速的黑客攻击,可能会让你接近你想要的东西:
import re
data=r'<wn20schema:NounSynset rdf:about="&dn;synset-56242" rdfs:label="{saddelmageri_1}">"'
matches=re.findall('synset-([0-9]+).*label="{(.*)_1}"', data)
print "matches:", matches
当我运行上面的代码时,我得到以下输出,这是一个包含你想要的两个字符串的两元组列表(虽然顺序不同):
matches: [('56242', 'saddelmageri')]
答案 2 :(得分:1)
如果您对这些数据做了很多,请考虑使用专门的RDF库(例如RDFLib)。 如果没有,那么XML解析器绝对是最佳选择!
label
将在about
之前?无论如何,我尝试应用XML解析器,但我在那里得到&dn;
的“未定义的实体错误”。你可以发布文件的顶部(doctype,命名空间定义等)吗?
答案 3 :(得分:1)
你在这里做了两种不同的解析,你需要使用两种不同的工具。
首先,您正在解析XML。为此,您将需要使用XML解析器,而不是正则表达式。因为这些元素在功能上是相同的XML:
<wn20schema:NounSynset rdf:about="&dn;synset-56242" rdfs:label="{saddelmageri_1}">
</wn20schema:NounSysnset>
<wn20schema:NounSynset rdf:about="&dn;synset-56242" rdfs:label="{saddelmageri_1}"/>
<wn20schema:NounSynset rdfs:label="{saddelmageri_1}" rdf:about="&dn;synset-56242"/>
甚至可以说:
<NounSynset xmlns="my_wn20schema_namespace_urn" C:label='not_of_interest' A:label='{saddelmageri_1}' B:about='&dn;synset-56242'/>
要解析该元素,您需要知道您感兴趣的元素和属性所属的命名空间的名称,然后使用XML解析器来查找它们 - 特别是,正确支持XML的XML解析器名称空间和XPath,如lxml。
你最终会得到这样的东西来找到你正在寻找的属性(假设doc
是解析的XML文档,而以_urn
结尾的变量是包含各种各样的字符串名称空间URN):
def find_attributes(doc):
for elm in doc.xpath('//x:NounSynset', namespaces={'x': wn20schema_namespace_urn}):
yield (elm.get(rdf_namespace_urn + "about"), elm.get(rdfs_namespace_urn + "label"))
现在您可以查看问题的第二部分,即从您拥有的属性值中解析所需的值。为此,您将使用正则表达式。要解析about
属性,这可能有效:
re.match(r'[^\d]*(\d*)', about).groups()[0]
返回找到的第一个数字字符系列。要解析label
属性,您可以使用:
re.match(r'{([^_]*)', label).groups()[0]
返回前导左括号后的label
中的所有字符,但不包括第一个下划线。 (至于解析你发布的label
的第二种形式,你还没有发布足够的信息来猜测要解析的正则表达式是什么样的。)