1

我很难理解这个正则表达式的东西......

我有一个这样的字符串:

<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']]

这样我以后可以将它作为 key(2589) 放入字典中: value(['cykel', 'trehjulet cykel', 'tricykel']) 对。

有什么想法吗?

4

4 回答 4

2

请参阅此问题最佳答案。使用正则表达式解析 xml 通常是一个糟糕的主意。XML 解析器就是为此目的而构建的。

最快的方法可能是 python 的内置 minidom

于 2009-12-28T15:46:58.510 回答
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')]
于 2009-12-28T15:47:40.290 回答
1

如果您对这些数据做了很多工作,甚至可以考虑使用专门的 RDF 库(例如 RDFLib)。如果没有,XML 解析器绝对是必经之路!

  • 如果明天它不在一条线上怎么办?
  • 如果明天label将在明天之前出现about怎么办?
  • 至少还有十几种方法可以保持 XML 的有效性,但会破坏您的正则表达式!

无论如何,我尝试应用 XML 解析器,但我得到了一个“未定义的实体错误” &dn;。您可以发布文件的顶部(文档类型、名称空间定义等)吗?

于 2009-12-28T16:36:44.823 回答
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 名称空间和 XPath 的 XML 解析器,如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您发布的第二种形式而言,您还没有发布足够的信息让我猜测要解析的正则表达式是什么样的。)

于 2009-12-28T16:55:36.297 回答