带有子模式异常的正则表达式模式 (Python)

Posted

技术标签:

【中文标题】带有子模式异常的正则表达式模式 (Python)【英文标题】:Regex pattern with subpattern exceptions (Python) 【发布时间】:2011-05-18 21:34:21 【问题描述】:

我正在使用 BeautifulSoup 从表中提取表数据标签。 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'))]

我需要提取所有类名为“a”和“不可用-可用”的 td。我一直在尝试一些负面的前瞻性断言,但运气不佳。我会重视任何能够产生正确正则表达式的正则表达式图例......

【问题讨论】:

你真的有 html"a' 条目显示的引号不匹配吗? 【参考方案1】:

我向其他人的 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'](必须使用dict 语法,因为class 是Python 关键字)。

【讨论】:

【参考方案2】:

哈!

re.compile('^a(?!vail)|^un')
匹配所有以 a 开头但不以 'vail' 开头的所有字符以及所有以 'un' 开头的字符。太好了!

【讨论】:

【参考方案3】:
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"

【讨论】:

+1 表示稳健性和明确搜索的内容。 您必须使用原始字符串,否则\s 将被误解。我冒昧地编辑了您的帖子。 @Tim:通常我会记得,但这次我忘了。感谢更新;那样更精确——尽管它不是更精确('\s' == '\\s' == r'\s',试试看)。如果它不起作用,我会注意到的,因为我确实尝试过。 啊,是的,你是对的。由于\s 在字符串中没有特殊含义,因此反斜杠将被视为文字。但是,\b 不会发生这种情况,例如('\b' == '\\b' 返回False)。

以上是关于带有子模式异常的正则表达式模式 (Python)的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式之基础

正则表达式

Python基础 - 正则表达式

如何编写正则表达式模式以匹配字符串结尾或字符串开头的货币符号

Python正则表达式,多行匹配模式..为啥这不起作用?

Python数据分析学习-re正则表达式模块