2009-03-03 22 views
4

Bir RSS 2.0 beslemesindeki başlık etiketini, o özet akışındaki her bir giriş için üç farklı değişkene ayrıştırmaya çalışıyorum. Gördüğünüz gibi, çünküPython ayrıştırma

ben dahil
feed = getfeed("http://www.tourfilter.com/dallas/rss/by_concert_date") 

for item in feed: 
print repr(item.title[0:-1]) 

, item.title olduğuna dair: Her başlık [eksi sondaki )] Aşağıdaki kodu ile yazdırmak böylece elementtree kullanma Zaten RSS ayrıştırıldı ettik Hakkında pek bilmediğim repr() veri türü.

interaktif penceresinde özel bir repr(item.title[0:-1])print ed şuna benzer:

'randy travis (Billy Bobs 3/21' 
'Michael Schenker Group (House of Blues Dallas 3/26' 

kullanıcı bir grup seçer ve ben umut, 3 değişkenler (bant, mekan birer ve içine her item.title ayrıştırma sonra tarih ... veya muhtemelen bir dizi veya bilmiyorum ...) sadece seçilen grupla ilgili olanları seçin. Daha sonra, coğrafi kodlama için Google'a gönderilir, ancak bu başka bir hikaye.

regex'dan bazı örnekler gördüm ve bunları okuyordum, ancak çok karmaşık görünüyor. Bu mu? Buradaki birisinin bunu nasıl akıllıca yapacağı konusunda bir fikir sahibi olabileceğini düşündüm. re modülünü kullanmalı mıyım? Çıktının şu anda repr() s olduğu önemli mi? Daha iyi bir yolu var mı? (Ben yazı ve bu da notların sadece tür benim pseudoPython olduğu) Ben gibi bir döngü kullanmak düşünüyordum:

 

    list = bandRaw,venue,date,latLong 
    for item in feed: 
     parse item.title for bandRaw, venue, date 
     if bandRaw == str(band) 
     send venue name + ", Dallas, TX" to google for geocoding 
     return lat,long 
     list = list + return character + bandRaw + "," + venue + "," + date + "," + lat + "," + long 
    else 

Sonunda, .csv seçilen girdileri (olmalı virgülle ayrılmış dosya şu şekilde görünebilir:

band,venue,date,lat,long 
randy travis,Billy Bobs,3/21,1234.5678,1234.5678 
Michael Schenker Group,House of Blues Dallas,3/26,4321.8765,4321.8765 

Umarım bu sormak için çok fazla değildir. Kendi başıma bakacağım, sadece cevap verdiğinden emin olmak için buraya göndermem gerektiğini düşündüm.

Yani, soru şu ki, her repr(item.title[0:-1])'u feed'da en iyi bir .csv dosyasında birleştirebileceğim 3 ayrı değere nasıl ayrıştırabilirim?

cevap

17

Regex'in sizi korkutmasına izin vermeyin ... öğrenmeye değer. ,

import re 
pat = re.compile('([\w\s]+)\(([\w\s]+)(\d+/\d+)\)') 
info = pat.match(s) 
print info.groups() 

('Michael Schenker Group ', 'House of Blues Dallas ', '3/26') 

her grup bireye ulaşmak için sadece info nesne üzerinde diyoruz:

Eğer geri sondaki parantez koyarak ve ardından bu modeli kullanmayı deneyin, yukarıdaki örnekler olabilir Verilen

print info.group(1) # or info.groups()[0] 

print '"%s","%s","%s"' % (info.group(1), info.group(2), info.group(3)) 
"Michael Schenker Group","House of Blues Dallas","3/26" 

Bu durumda regex hakkında zor olan şey, başlıktaki bilinen tüm karakterleri bildiğinizden emin olmaktır. 'Michael Schenker Group' bölümünde alfa olmayan karakterler varsa, izin vermek için o bölümün normal ifadesini ayarlamanız gerekir.

soldan sağa ayrıştırılır, hangi şöyle desen yukarıda ayırır:

([\w\s]+): herhangi bir kelime veya boşluk karakterleri eşleştirin (artı simgesi bir veya daha fazla bu tür karakterler olması gerektiğini belirtir). Parantezler, eşleşmenin bir grup olarak ele alınacağı anlamına gelir. Bu "Michael Schenker Grubu" kısmı. Burada rakamlar ve çizgiler varsa, parça için olası karakterler olan köşeli parantezler arasındaki parçaları değiştirmek isteyeceksiniz.Bir tamsayı parantezi. Ters eğik çizgi parantezden kaçar, aksi halde bir regex komutu olarak sayılır. . Yukarıdaki biri olarak aynı, ama bu kez bir parçası "Blues Dallas Evi" eşleşir parantez onlar ikinci grup olarak Çekilecek böylece

: Bu

([\w\s]+) dizesinin "(" parçasıdır..

(\d+/\d+): ortasında bir çizgi ile digits 3 ve 26 eşleşir parantez içinde, üçüncü bir grup olarak ele olur, böylece

\).:. yukarıda için parantez kapatma

düzenli ifade için piton intro. oldukça iyi ve ov bir akşam geçirmek isteyebilirsiniz http://docs.python.org/library/re.html#module-re. Ayrıca, samimi bir girişe sahip olan Python'a dalış yapın: http://diveintopython3.ep.io/regular-expressions.html.

DÜZENLEME: Bazı güzel düzenlemelere sahip olan aşağıdaki zacheratlara bakın. Bir elin nesi var iki elin sesi var!

+0

Cevabınız için teşekkürler! Bu çok yardımcı olur! Biraz kafam karıştı ... Alanları Google'a göndermek ve birleştirmek için tek tek belirlemem gerekiyor. Her bir değeri nasıl arayabilirim? Örneğin, değerleri nasıl birleştiririm? – Alan

+0

Regex, grup ve mekan adlarında sondaki boşlukları bırakır, ancak düzeltmesi kolaydır. –

+0

Evet, ben de fark ettim, ama her 'item.title' içindeki ilk iki değerde '[0: -1]' trickini çektiğimi düşündüm. – Alan

7

Düzenli ifadeler büyük Bu sorunun çözümü vardır: Bir yan not olarak

>>> import re 
>>> s = 'Michael Schenker Group (House of Blues Dallas 3/26' 
>>> re.match(r'(.*) \((.*) (\d+/\d+)', s).groups() 
('Michael Schenker Group', 'House of Blues Dallas', '3/26') 

, sen beslemeleri hatalı biçimlendirilmiş olmanın kötü bir alışkanlığı var olarak RSS ayrıştırma işlemek için Universal Feed Parser bakmak isteyebilirsiniz.

Düzenleme Yorumunuza ilgili olarak

... bazen "sarılmış olan dizeleri 's repr kullandığınız gerçeği ile ilgisi var ziyade bu. Bir dize repr olduğunu

>>> "Hello there" 
'Hello there' 
>>> "it's not its" 
"it's not its" 

Bildirimi farklı tırnak stilleri: 'lar öncelenmelidir gerekmez, böylece bunun yerine "s kullandığı s, 'o dize bir veya daha fazla içermediği sürece ler,' genellikle ile sınırlandırılmış.

+0

Cevabınız için teşekkürler! Yan notunuza gelince, bazı girişlerin "" ile başlangıç ​​ve bitişte "" ile çıktığını fark ettim. Bu bir problem olup olmayacağını merak ediyorum. Http://effbot.org/zone/element-rss-wrapper.htm adresinde bulunan RSS ayrıştırıcısını kullandım. – Alan

0

repr(item.title[0:-1]) bölümü ile ilgili olarak, nereden aldığınızdan emin değilim, ancak sadece item.title'u kullanabileceğinizden eminim. Yaptığın tek şey, son karakteri dizeden kaldırarak ... ... repr()'u arayarak ... ... hiçbir şey yapmıyor.

Kodunuz şöyle görünmelidir:

import geocoders # from GeoPy 
us = geocoders.GeocoderDotUS() 

import feedparser # from www.feedparser.org 
feedurl = "http://www.tourfilter.com/dallas/rss/by_concert_date" 
feed = feedparser.parse(feedurl) 

lines = [] 
for entry in feed.entries: 
    m = re.search(r'(.*) \((.*) (\d+/\d+)\)', entry.title) 
    if m: 
     bandRaw, venue, date = m.groups() 

     if band == bandRaw: 
      place, (lat, lng) = us.geocode(venue + ", Dallas, TX") 
      lines.append(",".join([band, venue, date, lat, lng])) 

result = "\n".join(lines) 

DÜZENLEME: var adı olarak lines ile list yerini aldı. list bir yerleşiktir ve değişken ad olarak kullanılmamalıdır. Afedersiniz.

+0

::: sigh ::: bütün şeyi daha az satırda yazdığımdan yaptığım gibi görünüyor. özellikle get_geo ve list.append için? Liste bir __builtin__, değil mi? get_geo? GeoPy'den mi? – Alan

+0

Ve son satır yeni satırı ekler? Bu da yararlıdır. Zaman ayırdığınız için teşekkürler. – Alan

+0

Üzgünüz olmasaydı üzgünüm, ama ben get_geo yaptım. Bunu uygulamaya karar verdiğiniz işlev için bir yer tutucu olarak kullandım. – itsadok

İlgili konular