4

I'm trying to parse the title tag in an RSS 2.0 feed into three different variables for each entry in that feed. Using ElementTree I've already parsed the RSS so that I can print each title [minus the trailing )] with the code below:

feed = getfeed("http://www.tourfilter.com/dallas/rss/by_concert_date")
for item in feed: 
 print repr(item.title[0:-1])

I include that because, as you can see, the item.title is a repr() data type, which I don't know much about.

A particular repr(item.title[0:-1]) printed in the interactive window looks like this:

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

The user selects a band and I hope to, after parsing each item.title into 3 variables (one each for band, venue, and date... or possibly an array or I don't know...) select only those related to the band selected. Then they are sent to Google for geocoding, but that's another story.

I've seen some examples of regex and I'm reading about them, but it seems very complicated. Is it? I thought maybe someone here would have some insight as to exactly how to do this in an intelligent way. Should I use the re module? Does it matter that the output is currently is repr()s? Is there a better way? I was thinking I'd use a loop like (and this is my pseudoPython, just kind of notes I'm writing):

 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 

In the end, I need to have the chosen entries in a .csv (comma-delimited) file looking like this:

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

I hope this isn't too much to ask. I'll be looking into it on my own, just thought I should post here to make sure it got answered.

So, the question is, how do I best parse each repr(item.title[0:-1]) in the feed into the 3 separate values that I can then concatenate into a .csv file?

asked Mar 3, 2009 at 19:25

3 Answers 3

17

Don't let regex scare you off... it's well worth learning.

Given the examples above, you might try putting the trailing parenthesis back in, and then using this pattern:

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')

To get at each group individual, just call them on the info object:

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"

The hard thing about regex in this case is making sure you know all the known possible characters in the title. If there are non-alpha chars in the 'Michael Schenker Group' part, you'll have to adjust the regex for that part to allow them.

The pattern above breaks down as follows, which is parsed left to right:

([\w\s]+) : Match any word or space characters (the plus symbol indicates that there should be one or more such characters). The parentheses mean that the match will be captured as a group. This is the "Michael Schenker Group " part. If there can be numbers and dashes here, you'll want to modify the pieces between the square brackets, which are the possible characters for the set.

\( : A literal parenthesis. The backslash escapes the parenthesis, since otherwise it counts as a regex command. This is the "(" part of the string.

([\w\s]+) : Same as the one above, but this time matches the "House of Blues Dallas " part. In parentheses so they will be captured as the second group.

(\d+/\d+) : Matches the digits 3 and 26 with a slash in the middle. In parentheses so they will be captured as the third group.

\) : Closing parenthesis for the above.

The python intro to regex is quite good, and you might want to spend an evening going over it http://docs.python.org/library/re.html#module-re. Also, check Dive Into Python, which has a friendly introduction: http://diveintopython3.ep.io/regular-expressions.html.

EDIT: See zacherates below, who has some nice edits. Two heads are better than one!

Bill the Lizard
407k213 gold badges579 silver badges892 bronze badges
answered Mar 3, 2009 at 19:35
Sign up to request clarification or add additional context in comments.

12 Comments

Thanks for your answer! That helps a lot! I'm a little confused though... I need to identify fields individually to send to Google and concatenate. How do I call each value? Like, for example, how would I concatenate the values?
Your regex leaves trailing spaces on the band and venue names, but that's easy to fix.
Yeah, I noticed that too, but figured I'd just pull the [0:-1] trick on the first two values in each item.title.
And his search for (.*) solves the character problem, so long as you don't set the regex to be greedy
I edited the post with some info on concatenating... hope I understood your intentions correctly.
|
7

Regular expressions are a great solution to this problem:

>>> 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')

As a side note, you might want to look at the Universal Feed Parser for handling the RSS parsing as feeds have a bad habit of being malformed.

Edit

In regards to your comment... The strings occasionally being wrapped in "s rather than 's has to do with the fact that you're using repr. The repr of a string is usually delimited with 's, unless that string contains one or more 's, where instead it uses "s so that the 's don't have to be escaped:

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

Notice the different quote styles.

answered Mar 3, 2009 at 19:35

1 Comment

Thanks for your answer! As to your side note, I have noticed that some of the entries come out with "" at the beginning and end rather than ''. I wonder if this will be a problem. I used the RSS parser available at effbot.org/zone/element-rss-wrapper.htm.
0

Regarding the repr(item.title[0:-1]) part, not sure where you got that from but I'm pretty sure you can simply use item.title. All you're doing is removing the last char from the string and then calling repr() on it, which does nothing.

Your code should look something like this:

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)

EDIT: replaced list with lines as the var name. list is a builtin and should not be used as a variable name. Sorry.

answered Mar 3, 2009 at 20:22

3 Comments

:::sigh::: looks like you wrote the whole thing in less lines than I have imports... what modules are you using? especially for the get_geo and list.append? list is a builtin, right? get_geo? is that from GeoPy?
And the last line adds the newline? That's helpful, too. Thanks for taking the time.
Sorry if it wasn't clear, but I made up get_geo. I just used it as a placeholder for whatever function you decide to implement.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.