2011-12-27 52 views
1

需要使用re模塊在Python中的href屬性標籤之間拉字符串。新手Python /正則表達式:使用正則表達式在<a>標籤之間拉字符串

我已經試過無數的圖案,如:

patFinderLink = re.compile('\>"(CVE.*)"\<\/a>') 

例子:我需要從拉是什麼(在這種情況下, 「CVE-2010-3718」)標記之間:

<pre> 
<a href="https://www.redhat.com/security/data/cve/CVE-2010-3718.html">CVE-2010-3718</a> 
</pre> 

我在這裏做錯了什麼?任何意見是極大的讚賞。先謝謝你。

太陽

回答

0

我很驚訝沒有人建議用BeautifulSoup:

這裏是我會怎麼做:

from BeautifulSoup import BeautifulSoup 
import re 

hello = """ 
<pre> 
<a href="https://www.redhat.com/security/data/cve/CVE-2010-3718.html">CVE-2010-3718</a> 
<a href="https://www.redhat.com/security/data/cve/CVE-2010-3710.html">CVE-2010-3718</a> 
<a href="https://www.redhat.com/security/data/cve/CVE-2010-3700.html">CVE-2010-3718</a> 
</pre> 
""" 

target = re.compile("CVE-\d+-\d+.html") 
commentSoup = BeautifulSoup(hello) 
atags = commentSoup.findAll(href=target) 
for a in atags: 
    match = re.findall(target, a['href'])[0] 
    print match 

結果:

CVE-2010-3718.html 
CVE-2010-3710.html 
CVE-2010-3700.html 
+0

儘管其他答案提出了更優雅的解決方案,這一個爲我捏了一把。謝謝。 – user1117603 2011-12-27 22:30:09

6

你需要使用正則表達式嗎?我不認爲你這樣做,你不能用正則表達式解析SGML,因爲SGML本身並不經常,請參閱這個着名的計算器回答的推理:https://stackoverflow.com/a/1732454/88123

無論如何。您應該使用lxml Python模塊及其xpath實現。 xpath支持選擇以開頭的文本。

XPath在這種情況下將是//h1/text()

或者,使用Python模塊BeautifulSoup

+0

+1對於lxml,我會爲着名的反註冊答案給出另一個+1! – 2011-12-27 13:13:08

+0

'// h1/text()'? – Acorn 2011-12-27 13:15:30

+0

@Acorn - 我實際上看過他鏈接的頁面,看到了h1中表示的CVE編號。 – ikanobori 2011-12-27 13:16:23

2

不要試圖使用正則表達式來解析HTML或XML。使用解析器,如lxml

import lxml.html as lh 

tree = lh.fromstring(html) 

print tree.xpath("//pre/a[starts-with(., 'CVE')]/text()") 

結果:

 
['CVE-2010-3718'] 
+0

_lxml_至少比正則表達式慢20倍。事實上,我有一天測量了100次,但它可能並不代表中等量的_lxml_解決方案的時間超過正則表達式解決方案,所以我更願意說20 ..... – eyquem 2011-12-27 14:25:23

0

如果你仍然想使用HTML正則表達式解析(雖然它不是建議作爲被alredy提到的 - 但我不知道爲什麼)試試這個:

a = re.compile('<a href=".*">(.*)</a>') 
result = a.match(string).group(0) 

結果將包含CVE-2010-3718

1

使用

re.compile('">(CVE.*?)</a>') 

# instead of your re.compile('\>"(CVE.*)"\<\/a>') 

注意的是字符<> /不需要在正則表達式模式

進行轉義並注意.*?字符停止以便量詞*的貪婪行爲的匹配在第一個</a>受到阻止時停止。關於這一點請參閱文檔,這是基本的

有時使用re時,分析一個XML有問題| GML文本
有一次,我被告知,一個可能的問題是,標籤可以在幾行寫,例如:

ss = ''' 
<pre> 
    <a href="https://www.redhat.com/security/data/cve/CVE-2010-3718.html">CVE-20 
    10-371 
    8</a> 
</pre>''' 

在這種情況下,不會有任何匹配,因爲在正則表達式模式中用作符號的點不會象徵換行符'\ n'。因此該模式的.*?部分將不允許按行運行。

要糾正此問題,請使用re.DOTALL規範,該規範爲點符號提供了表示任何和所有字符的權力。

請注意,常見的信念是,不得使用工具來解析SGML或XML文本。但很少有人能夠徹底解釋爲什麼。我是其中一個不知道原因的人。

但個人而言,我認爲正則表達式可以用來分析文本。我寫'分析'而不是'PARSE'。

據我所知,解析是分析文本和基於標籤構建樹形表示的過程。
雖然我將文本分析定義爲...分析它,但沒有獲得樹表示的目的。
當樹形表示不需要從文本中提取數據時,請使用正則表達式,並且不要聽那些對這個主題有宗教考慮的人,比如在有趣但欺騙性(在我看來)的帖子中,其鏈接已被鑑於

0

正如其他人已經建議的,正則表達式通常不是HTML解析的好工具。

但是,如果你想使用正則表達式,這是我怎麼會提取<a> </a>標籤之間的兩個URL的所有元組和內容的一個例子:

import re 

#example html string with various hits 
html_string = """ 
    <pre> 
    <a href="https://www.redhat.com/security/data/cve/CVE-2010-3718.html">CVE-2010-3718</a> 
    <a href="https://www.redhat.com/security/data/cve/CVE-2010-3710.html">CVE-2010-3710</a> 
    <a href="https://www.redhat.com/security/data/cve/CVE-2010-3700.html">CVE-2010-3700</a> 
    </pre> 
""" 

#regular expression: 
pattern = re.compile('<a href=([^>]*)>([^<]*)</a>') 

#find all matches in our html string: 
tuples = pattern.findall(html_string) 

for tuple in tuples: 
    print "%s —> %s" % (tuple[1], tuple[0]) 

正如其他人所提到的,LXML將是一個更適合工具。

如果你打算這樣做,我建議你按照@Acorn的回覆。

相關問題