Возможно, это проще без регулярных выражений.Это работает с BeautifulSoup 3:
from BeautifulSoup import BeautifulSoup
page = """
<tr class="class1 class2 class3">1</tr>
<tr class="class1 class2 class3">2</tr>
<tr class="class1 class5">3</tr>
<tr class="class1_a class5_a">4</tr>
<tr class="class1 class5">5</tr>
<tr class="class1_a class5_a">6</tr>
<tr>7</tr>"""
def cond(x):
if x:
return x.startswith("class1") and not "class2 class3" in x
else:
return False
soup = BeautifulSoup(page)
rows = soup.findAll('tr', {'class': cond})
for row in rows:
print row
=>
<tr class="class1 class5">3</tr>
<tr class="class1_a class5_a">4</tr>
<tr class="class1 class5">5</tr>
<tr class="class1_a class5_a">6</tr>
С BeautifulSoup 4 я смог заставить его работать следующим образом:
import re
from bs4 import BeautifulSoup
page = """
<tr class="class1 class2 class3">1</tr>
<tr class="class1 class2 class3">2</tr>
<tr class="class1 class5">3</tr>
<tr class="class1_a class5_a">4</tr>
<tr class="class1 class5">5</tr>
<tr class="class1_a class5_a">6</tr>
<tr>7</tr>"""
soup = BeautifulSoup(page)
rows = soup.find_all('tr', {'class': re.compile('class1.*')})
for row in rows:
cls = row.attrs.get("class")
if not ("class2" in cls or "class3" in cls):
print row
=>
<tr class="class1 class5">3</tr>
<tr class="class1_a class5_a">4</tr>
<tr class="class1 class5">5</tr>
<tr class="class1_a class5_a">6</tr>
В BS4 многозначные атрибуты, такие как class
, имеют списки строк в качестве значений, а не строки.Смотри http://www.crummy.com/software/BeautifulSoup/bs4/doc/#id12.