2009-12-28 57 views
1

我有一個很難理解這個表達式的東西...Python的正則表達式找到兩個關鍵詞在一條線上

我有一個這樣的字符串:

<wn20schema:NounSynset rdf:about="&dn;synset-56242" rdfs:label="{saddelmageri_1}"> 

我想的findAll使用()和團體得到這樣的:

['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'))對。

有什麼想法?

+5

不要使用錘子來切割火雞(閱讀:這是使用正則表達式的情況下)。 – balpha 2009-12-28 15:41:30

+0

@balpha,+1!您應該改用XML解析器。 – 2009-12-28 15:42:44

回答

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')] 
+0

這對我的問題做了詭計! 但是,你是對的,我不是很精確。碰巧,它並不總是_1,它可能是_2或更多。甚至有時候,如果沒有任何字詞會以DN作爲前綴,如{DN:saddelmageri}。 我想你沒問題,使用XML解析器一定更容易。 – SupsH 2009-12-28 15:55:25

2

請參閱最佳答案this question。用正則表達式解析xml通常是一個糟糕的主意。 XML解析器是爲此目的而構建的。

這樣做很可能是最快捷的方式python的built-in minidom

1

如果你做了很多與此數據,即使考慮一個專門的RDF庫(如RDFLib)。 如果不是,XML解析器絕對是您的選擇!

  • 如果明天它不會在一條線上呢?
  • 如果明天label會在about之前出現?
  • 至少有十多種方法可以保持有效的XML,但打破你的正則表達式!

無論如何,我嘗試應用XML解析器,但我得到一個「未定義的實體錯誤」爲&dn;那裏。你能發佈文件的頂部(doctype,名稱空間定義等)嗎?

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,你還沒有發佈足夠的信息讓我猜測看起來像什麼樣的正則表達式。)

相關問題