Normal ifade eşleşmesinin bir bölümünü ayıklayın


131

Başlığı bir HTML sayfasından çıkarmak için normal bir ifade istiyorum. Şu anda buna sahibim:

title = re.search('<title>.*</title>', html, re.IGNORECASE).group()
if title:
    title = title.replace('<title>', '').replace('</title>', '') 

Etiketleri kaldırmak zorunda kalmamam için yalnızca <title> içeriğini ayıklamak için normal bir ifade var mı?


5
vay, sadece basit bir başlık çıkarmak için tüm HTML sayfasını ayrıştırmaya çağıran tüm yanıtlara inanamıyorum. Ne abartı!
hoju

4
Soru başlığı her şeyi anlatıyor - verilen örnek HTML oluyor , ancak genel sorun ... genel.
Phil

Yanıtlar:


209

Yakalanan dizeyi almak için ( )regexp ve python'da kullanın group(1)( sonucu bulamazsa re.searchgeri dönecektir None, bu yüzden doğrudan kullanmayıngroup() ):

title_search = re.search('<title>(.*)</title>', html, re.IGNORECASE)

if title_search:
    title = title_search.group(1)

1
Başlık bulunmadığında hiçbir şey yapmıyorsanız, group () 'u doğrudan kullanmak neden kötü olur? (yine de istisnayı yakalayabilirsiniz)
tonfa

1
evet, ama çoğu insan istisnaları unutuyor ve çalışma zamanında gördüklerinde gerçekten şaşırıyor :)
Krzysztof Krasoń

Koşmayı unutma import reyoksa alacaksınNameError: name 're' is not defined
Powers

16

Atama ifadelerinin başlatılması Python 3.8ve tanıtılması (PEP 572) ( :=operatör), Krzysztof Krasoń'un çözümünü bir değişken olarak doğrudan if koşulu içinde yakalayarak ve koşulun gövdesinde yeniden kullanarak bir bit iyileştirmenin mümkün olduğunu unutmayın. :

# pattern = '<title>(.*)</title>'
# text = '<title>hello</title>'
if match := re.search(pattern, text, re.IGNORECASE):
  title = match.group(1)
# hello

6

Yakalama grupları kullanmayı deneyin:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)


4

Sizi Güzel Çorba'ya tavsiye edebilir miyim? Soup, tüm html belgenizi ayrıştırmak için çok iyi bir kitaplıktır.

soup = BeatifulSoup(html_doc)
titleName = soup.title.name

Eklemek isterim ki, bu güzel grup aynı zamanda eksik html'yi de ayrıştırıyor ve bu gerçekten güzel.
2013

3

Deneyin:

title = re.search('<title>(.*)</title>', html, re.IGNORECASE).group(1)

HTML ayrıştırması için REGEX'i gerçekten kullanmak istiyorsanız, .group () işlevini doğrudan eşleşmede çalıştırmayın, aksi takdirde Yok döndürebilir.
iElectric

Belgede .*?birden fazla olması durumunda bunu kullanmalısınız </title>(olası değildir, ancak asla bilemezsiniz).
tonfa

@iElectric: Gerçekten istiyorsan, blok dışında bir deneyebilirsin, değil mi?
tonfa

3

Sağlanan kod parçaları Exceptions Mayıs ile baş etmiyor

getattr(re.search(r"<title>(.*)</title>", s, re.IGNORECASE), 'groups', lambda:[u""])()[0]

Bu, kalıp bulunamazsa veya ilk eşleşirse varsayılan olarak boş bir dize döndürür.


1

Bunun yeterli olacağını düşünüyorum:

#!python
import re
pattern = re.compile(r'<title>([^<]*)</title>', re.MULTILINE|re.IGNORECASE)
pattern.search(text)

... metninizin (HTML) "metin" adlı bir değişkende olduğu varsayılarak.

Bu aynı zamanda, bir HTML TITLE etiketinin içine yasal olarak gömülebilecek başka HTML etiketlerinin olmadığını ve bu tür bir kap / blok içerisine başka herhangi bir <karakterini yasal olarak gömmenin bir yolu olmadığını varsayar.

Ancak ...

Python'da HTML ayrıştırması için normal ifadeler kullanmayın. Bir HTML ayrıştırıcı kullanın! (Tam bir ayrıştırıcı yazmayacaksanız, bu, çeşitli HTML, SGML ve XML ayrıştırıcıları zaten standart kitaplıklarda olduğunda fazladan bir iş olacaktır.

Eğer "gerçek dünya" etiketini işliyorsanız (ki bu genellikle herhangi bir SGML / XML doğrulayıcıya uymamaktadır), o zaman BeautifulSoup paketini kullanın . Standart kitaplıklarda yoktur (henüz) ancak bu amaç için yaygın olarak önerilir.

Diğer bir seçenek ise: lxml ... düzgün yapılandırılmış (standartlara uygun) HTML için yazılmıştır. Ancak BeautifulSoup'u ayrıştırıcı olarak kullanmaya geri dönüş seçeneği vardır: ElementSoup .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.