【问题标题】:python re.findall pattern for different number of matchespython re.findall 模式用于不同数量的匹配
【发布时间】:2016-02-24 21:08:48
【问题描述】:
<tr>
11:15
12:15
13:15
</tr>

<tr>
18:15
19:15
20:15
</tr>

in this case output should be: [ (11:15, 12:15, 13:15), (18:15, 19:15, 20:15) ]

我的模式:(\d\d:\d\d)[\s\S]*?(\d\d:\d\d)[\s\S]*?(\d\d:\d\d)[\s\S]*?&lt;/tr&gt; 仅当每个 tr 标签中有 3 小时时才有效

但是如果每个 tr 标签中有 1-3 小时(格式相同 \d\d​​:\d\d),这应该可以工作。 另一个例子。为此,我的模式不再适用。

<tr>12:00 13:00</tr>
<tr>14:00 15:00 16:00</tr>
<tr>12:00</tr>

Output should be: [ (12:00, 13:00, ), (14:00, 15:00, 16:00), (12:00, , ) ]

还有一件事:每个小时不只是由空格分隔,真正的文件看起来像这样: 我为此使用了[\s\S]*? or [\w\s&lt;&gt;="-/:;?|]*?。一个小时要么是简单的跨度,要么是更长的形式 .

示例:

<tr>
<span class="na">16:00</span>
<span>|</span><a href="http:/21.28.147.68/msi/default.aspx?event_id=52514&amp;typetran=1&amp;ReturnLink=http://www.kino.pl/kina/przedwiosnie/repertuar.php" class="toolBox" data-hasqtip="true" aria-describedby="qtip-0">20:45</td>
</tr>

【问题讨论】:

  • 别告诉我你是using regex to parse html
  • [\s\S]不等于.吗?
  • [\s\S] 匹配任何内容,包括 newline ,而 . 不匹配。
  • @user1858268 除非你使用re.DOTALL 作为标志。
  • 对于现实生活中的例子,您不应该这样做:re.findall('\d\d:\d\d', target_source)吗?

标签: python regex findall


【解决方案1】:

我会使用 HTML 解析器 解析 HTML,找到 table 中的所有 tr 元素并使用 str.split() 拆分内容或每一行 - 它会同时处理空格和换行符.使用BeautifulSoup parser 的示例:

from bs4 import BeautifulSoup

data = """
<table>
    <tr>
    11:15
    12:15
    13:15
    </tr>

    <tr>
    18:15
    19:15
    20:15
    </tr>

    <tr>12:00 13:00</tr>
    <tr>14:00 15:00 16:00</tr>
    <tr>12:00</tr>
</table>"""

soup = BeautifulSoup(data, "html.parser")

result = [row.text.split() for row in soup.table.find_all("tr")]
print(result)

打印:

[['11:15', '12:15', '13:15'], 
 ['18:15', '19:15', '20:15'], 
 ['12:00', '13:00'], 
 ['14:00', '15:00', '16:00'], 
 ['12:00']]

一个小时要么是简单的跨度,要么是更长的形式。

这样就更好了,让我们找到tr中的每个内部元素匹配特定模式并获取文本

[[elm.strip() for elm in row.find_all(text=re.compile(r"\d\d:\d\d"))] 
 for row in soup.table.find_all("tr")]

【讨论】:

  • @kierrez 您能否编辑问题并将这个真正的 html sn-p 插入问题中?谢谢。
  • @kierrez 如果您正在做任何复杂的事情,那么您绝对应该使用 HTML 解析器。
  • @kierrez 抱歉多次更新,现在您可以查看更新后的代码示例。
  • 哇,谢谢。我这样做了 3 天......我从未听说过 HTML 解析器,但我将从现在开始使用它
【解决方案2】:

如果你更喜欢正则表达式,你可以使用这个:

found = []
for group in re.findall(r'(\d\d:\d\d.*){1,3}</tr>', data, re.DOTALL):
    found.append(re.findall(r'(\d\d:\d\d)', group, re.DOTALL))
# found == [['12:00', '13:00'], ['14:00', '15:00', '16:00'], ['12:00']]

【讨论】:

    【解决方案3】:

    使用正则表达式尝试此解决方案:

    import re
    
    input = """
    <tr>
    11:15
    12:15
    13:15
    </tr>
    
    <tr>
    18:15
    19:15
    20:15
    </tr>
    
    <tr>12:00 13:00</tr>
    <tr>14:00 15:00 16:00</tr>
    <tr>12:00</tr>
    """
    
    print [ re.findall('(\d\d:\d\d)', tr) for tr in re.findall('<tr>([^<]*)</tr>', input)] 
    

    输出:

    [['11:15', '12:15', '13:15'], 
     ['18:15', '19:15', '20:15'], 
     ['12:00', '13:00'], 
     ['14:00', '15:00', '16:00'], 
     ['12:00']]
    

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-27
      • 1970-01-01
      相关资源
      最近更新 更多