Remove (not extract) timestamp from HTML string I've got strings coming from irregularly and ugly formatted HTML sites, that contain a timestamp. I am interested in removing the timestamp entirely and get all the rest.

from bs4 import BeautifulSoup

date1 = '&lt;P&gt;&lt;SPAN STYLE="font-family: Univers" STYLE="font-size: 11pt"&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN STYLE="font-family: Univers" STYLE="font-size: 11pt"&gt;10:15 AM  ARVIND KRISHNAMURTHY, Northwestern University&lt;/SPAN&gt;&lt;/P&gt;'
date2 = """&lt;tr&gt;&lt;td style="width:1.2in;padding:0in 5.4pt 0in 5.4pt" valign="top" width="115"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:11.0pt;font-family:Univers"&gt;&lt;span style="mso-spacerun: yes"&gt; &lt;/span&gt;8:45 a.m.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td style="width:5.45in;padding:0in 5.4pt 0in 5.4pt" valign="top" width="523"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-size:11.0pt;font-family:Univers"&gt;RICARDO  CABALLERO, MIT and NBER&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;"""

soup1 = BeautifulSoup(date1)
print repr(soup1.text.strip())
# "u'10:15 AM  ARVIND KRISHNAMURTHY, Northwestern University'"
soup2 = BeautifulSoup(date2)
print repr(soup2.text.strip())
# "u'8:45 a.m.RICARDO  CABALLERO, MIT and NBER'"


Now, to get the text following the timestamp, I split along whitespaces to join all elements, except the first two:

def remove_date(aString):
    cleaned = aString.replace("\t", " ").replace(".m.", " ").strip()
    return " ".join(cleaned.split(" ")[ 2:]).strip()

string1 = remove_date(soup1.text.strip())
print repr(string1)
# u'ARVIND KRISHNAMURTHY, Northwestern University'
string2 = remove_date(soup2.text.strip())
print repr(string2)
# u'RICARDO  CABALLERO, MIT and NBER'


It delivers the desired result, but this is arguably very ugly. Is there something better? Maybe something that works like dateutil.parser.parse(), but in reverse?
You're right that it's ugly, I thought it didn't work at first until I realised how you're splitting to remove the first two whitespace separated strings. It's very unclear and very specific to these formats. If you're going to be format specific, then shouldn't you just use a regex?

r'^\d+:\d+\s+(am|pm|a\.m\.|p\.m\.)' will match the format in both the provided cases.

A brief breakdown is that it will match digits, then a colon, then digits again, then whitespace followed by either am, pm, a.m. or p.m.. You can make it case insensitive to avoid manually marking upper cases too. Also the ^ at the start means it will only work on strings that have this pattern at the beginning, so it wouldn't affect strings that happen to include similar formats as part of the text. I used this site for figuring out this regex and it's very helpful for stuff like this.

You can compile this regex simply with this:

import re

pattern = re.compile(ur'^\d+:\d+\s+(am|pm|a\.m\.|p\.m\.)', re.IGNORECASE)


Then just call it on your stripped soup text:    

string1 = re.sub(pattern, "", soup1.text.strip())
print repr(string1)
string2 = re.sub(pattern, "", soup2.text.strip())
print repr(string2)