带有子模式例外的正则表达式模式(Python)

3
我正在使用BeautifulSoup从表格中提取tabledata标签。TD的类别有'a','u','e','available-unavailable'或'unavailable-available'。(是的,我知道这些类名很奇怪,但是...)
下面是一个例子:
<tr>
  <td class="u">4</td>
  <td class="unavailable-available">5</td>
  <td class="a'>6</td>
  <td class="available-unavailable">7</td>
  <td class="u">8</td>
  ...

我一直在使用一个包含re.compile()的代码行:

  tab = [int(tag.string) for tag in soup.find('table',{'summary':tableSummary}).findAll("td", attrs = {"class": re.compile('\Aa')})]

我需要提取所有class名称为'a'和'unavailable-available'的td元素。我一直在尝试一些负向先行断言,但没有什么好运气。我希望能得到任何能够产生正确正则表达式的正则表达式专家的帮助...


你真的有带有不匹配引号的HTML代码吗?就像“a'”这个条目所显示的那样? - PaulMcG
3个回答

2
table.findAll('td', attrs = {"class":re.compile(r'(^|\s)(a|unavailable-available)($|\s)')})

这个匹配模式是匹配字符串开头或空格后跟着 "a" 或 "unavailable-available",然后是空格或字符串结尾。因此,它将匹配所有这些类型的内容。

class="a"
class="a ui-xxx"
class="ui-xxx a"
class="ui-xxx a ui-yyy"
class="unavailable-available"
class="unavailable-available foo"

在编程中,强调鲁棒性和明确搜索对象是非常重要的。 - Karl Knechtel
你必须使用原始字符串,否则\s会被错误解释。我有修改过你的帖子。 - Tim Pietzcker
@Tim:通常我会记得,但这次我忘了。感谢你更新它;那样更精确 - 虽然不更准确('\s' == '\\s' == r'\s',试试看)。如果它没有起作用,我会注意到的,因为我确实尝试过。 - Chris Morgan
啊,没错。由于\s在字符串中没有特殊含义,因此反斜杠会被视为字面量。但是这种情况不会发生在\b上,例如('\b' == '\\b'返回False)。 - Tim Pietzcker

0

哈!

re.compile('^a(?!vail)|^un')
  • 匹配所有以'a'开头但不是紧跟着'vail'的字符串和所有以'un'开头的字符串。好样的,un!

0
我向其他人的RE技能致敬。但作为BS+RE的替代数据点,这里是一个pyparsing版本(假设那些讨厌的不匹配引号得到修复):
html = """
<tr> 
  <td class="u">4</td> 
  <td class="unavailable-available">5</td> 
  <td class="a">6</td> 
  <td class="available-unavailable">7</td> 
  <td class="u">8</td> 
"""

from pyparsing import makeHTMLTags, withAttribute, oneOf, SkipTo

# define opening and closing tag expressions
td,tdEnd = makeHTMLTags("TD")

# only want opening TD's with certain classes
td.setParseAction(withAttribute(**{'class':oneOf("a unavailable-available")}))

# define overall pattern
patt = td + SkipTo(tdEnd)("contents") + tdEnd

# search for matches
for t in patt.searchString(html):
    print t.dump()

输出:

['TD', ['class', 'unavailable-available'], False, '5', '</TD>']
- class: unavailable-available
- contents: 5
- empty: False
- endTd: </TD>
- startTd: ['TD', ['class', 'unavailable-available'], False]
  - class: unavailable-available
  - empty: False
['TD', ['class', 'a'], False, '6', '</TD>']
- class: a
- contents: 6
- empty: False
- endTd: </TD>
- startTd: ['TD', ['class', 'a'], False]
  - class: a
  - empty: False

对于每个匹配项,您还可以直接访问t.contentst['class'](必须使用字典语法,因为class是Python关键字)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接