2009-05-11 10 views
6

düşünün dizeleri iki takım arasında bir dize bulmak için:Python - - Regex Nasıl aşağıdaki

Eğer piton yılında regex ile site haritası çizgisini çıkarmayı gider nasıl
<div id=hotlinklist> 
    <a href="foo1.com">Foo1</a> 
    <div id=hotlink> 
    <a href="/">Home</a> 
    </div> 
    <div id=hotlink> 
    <a href="/extract">Extract</a> 
    </div> 
    <div id=hotlink> 
    <a href="/sitemap">Sitemap</a> 
    </div> 
</div> 

?

<a href="/sitemap">Sitemap</a> 

Aşağıdakiler bağlantı etiketlerini çıkarmak için kullanılabilir. Ancak, birden çok bağlantı etiketi vardır. Ayrıca birden fazla hotlink (ler) var, bu yüzden onları gerçekten kullanamıyoruz?

+0

bir bağlam-ayrıştırmak için HTML gibi bir dil. – Gumbo

+2

Bu HTML'yi oluşturan siz iseniz, bunun gibi çoklu, aynı "id =" özelliklerinin geçerli olmadığını unutmayın. Bir 'class =' daha uygundur. –

cevap

13

Bir düzenli ifadeyi kullanmayın. Bir HTML ayrıştırıcısı olan BeautfulSoup kullanın.

from BeautifulSoup import BeautifulSoup 

html = \ 
""" 
<div id=hotlinklist> 
    <a href="foo1.com">Foo1</a> 
    <div id=hotlink> 
    <a href="/">Home</a> 
    </div> 
    <div id=hotlink> 
    <a href="/extract">Extract</a> 
    </div> 
    <div id=hotlink> 
    <a href="/sitemap">Sitemap</a> 
    </div> 
</div>""" 

soup = BeautifulSoup(html) 
soup.findAll("div",id="hotlink")[2].a 

# <a href="/sitemap">Sitemap</a> 
6

HTML'yi normal ifade ile ayrıştırma kötü bir fikirdir!

daha pekçok örnek var html

aşağıdaki parça hakkında düşünün. Düzenli ifadeler birçok şey için iyidir, ancak HTML'yi ayrıştırmak için uygun değildir.

Beautiful Soup python HTML ayrıştırıcısını kullanmayı düşünmelisiniz. HTML ayrıştırmak gerekiyorsa

>>> e.findall(data) 
['<a href="foo1.com">Foo1</a>', '<a href="/">Home</a>', '<a href="/extract">Extract</a>', '<a href="/sitemap">Sitemap</a>'] 
+0

Eğer '. *' Yerine '(?: [^ <] + | <(!/A \ b)) *' ile değiştirirseniz, regex motorunu geriye dönük olarak kaldırmadan daha az hatalı pozitif sonuç alırsınız. –

1

kullanın BeautifulSoup veya lxml:

neyse, regex kullanarak bir ad-hoc çözüm

import re 

data = """ 
<div id=hotlinklist> 
    <a href="foo1.com">Foo1</a> 
    <div id=hotlink> 
    <a href="/">Home</a> 
    </div> 
    <div id=hotlink> 
    <a href="/extract">Extract</a> 
    </div> 
    <div id=hotlink> 
    <a href="/sitemap">Sitemap</a> 
    </div> 
</div> 
""" 

e = re.compile('<a *[^>]*>.*</a *>') 

print e.findall(data) 

Çıktı olduğunu.

Ayrıca, gerçekten yapmanız gereken nedir? Son bağlantıyı buldunuz mu? Üçüncü bağlantıyı buldunuz mu?/Sitemap'a işaret eden bağlantıyı bulun? Senin sorunundan belli değil. Verilerle do yapabilmeniz için neye ihtiyacınız var?

Gerçekten normal ifadeler kullanmanız gerekiyorsa, findall'a bakın. sloganlı içeriğini ayıklamak için

5

:

<a href="/sitemap">Sitemap</a> 

... Ben kullanırsınız: Muhtemelen bunu düzenli ifadeler uygun değildir duyar

>>> import re 
    >>> s = ''' 
    <div id=hotlinklist> 
    <a href="foo1.com">Foo1</a> 
     <div id=hotlink> 
     <a href="/">Home</a> 
     </div> 
     <div id=hotlink> 
     <a href="/extract">Extract</a> 
     </div> 
     <div id=hotlink> 
     <a href="/sitemap">Sitemap</a> 
     </div> 
    </div>''' 
    >>> m = re.compile(r'<a href="/sitemap">(.*?)</a>').search(s) 
    >>> m.group(1) 
    'Sitemap' 
+0

Aslında, bir şey olabileceğinden, site haritasını XYZ ile değiştirin. Ben sadece hotlinlist div içinde 3. div olduğunu biliyorum. Kullanılan html deseni birçok kez tekrarlanabilir. Diyelim ki, ebay'daki tüm akıllı telefonları çıkarmak istiyorum. Yukarıdaki modelin bulunan her akıllı telefon için yineleneceğini bilmekteyim, ancak, XYZ bir iphone, böğürtlen, Nokia veya başka bir akıllı telefon olabilir. Hiçbir eşya ya da 100 olabilir. Böylece, tekrarlanan modeli bulduktan sonra akıllı telefon hattını alıp akıllı telefonların bir listesine sahip olan bir şey arıyordum. – un33k

+0

Soruyu cevaplarken bunu beğendim. Ayrıca, regex'in daha iyi olduğuna inanmamda bana yardımcı oldu. – Max