【问题标题】:Python finding multiple regex matches within a regex matchPython在正则表达式匹配中查找多个正则表达式匹配
【发布时间】:2018-11-05 00:53:48
【问题描述】:

我正在尝试使用 re.sub() 将所有 html 标签 < 和 > 更改为 { 和 }。问题是:我只想更改<table 和</table> 之间的匹配。

我一生都找不到一个正则表达式教程或帖子,其中一个能够更改每个正则表达式匹配,但只能在其他两个正则表达式匹配之间。我看过正面/负面的前瞻和后视教程等,但没有运气。在决定发布之前已经进行了几个小时的搜索。

这是我目前为止最好的:

(?<=<table)(?:.*?)(<)(?:.*)(?=<\/table>)

这将匹配表格开始和结束标记之间的一个“

所有这一切的重点是,我有一个包含大量 HTML 的字符串,我想将所有 HTML 标记以及表格本身保留在表格中。

我目前的计划是将表格中的所有标签(以及表格标签本身)更改为 { 或 },然后删除整个文档中的所有 HTML 标签 ,然后将所有 { 和 } 更改回 。这样做应该保留表格(以及里面的任何其他标签)。

输入示例:

<font style = "font-family:inherit>
<any other HTML tags>

random text

<table cellpadding="0" cellspacing="0" style="font-family:times new 
roman;font-size:10pt;width:100%;border-collapse:collapse;text-align:left;">
<tr>
<td colspan="3">
<font style="font-family:inherit;font-size:12pt;font- 
weight:bold;">washington, d.c. 20549</font>
random text
<any other HTML tags within table tags>
</td>
</table>

random text

<font style = "font-family:inherit>

输出示例:

<font style = "font-family:inherit>
<any other HTML tags>

random text

{table cellpadding="0" cellspacing="0" style="font-family:times new 
roman;font-size:10pt;width:100%;border-collapse:collapse;text-align:left;"}
{tr}
{td colspan="3"}
{font style="font-family:inherit;font-size:12pt;font- 
weight:bold;"}washington, d.c. 20549{/font}
random text
{any other HTML tags within table tags}
{/td}
{/table}

random text

<font style = "font-family:inherit>

谢谢你, 熟食

【问题讨论】:

  • 请举例说明你的html以及替换后你想要什么。
  • 我刚刚使用示例输入和输出进行了编辑。谢谢你让我知道,我很感激。

标签: python regex regex-lookarounds


【解决方案1】:

正如 Serge 所提到的,这并不是你想用一个正则表达式来解决的问题,而是用多个正则表达式和一些 python 魔法来解决的:

def replacer(match):  # re.sub can take a function as the repl argument which gives you more flexibility
    choices = {'<':'{', '>':'}'}  # replace < with { and > with }
    return choices[match.group(0)]

result = []  # store the results here
for text in re.split(r'(?s)(?=<table)(.*)(?<=table>)', your_text): # split your text into table parts and non table parts
    if text.startswith('<table'): # if this is a table part, do the <> replacement 
        result.append(re.sub(r'[<>]', replacer, text))
    else: # otherwise leave it the same
        result.append(text)
print(''.join(result)) # join the list of strings to get the final result

查看文档以将函数用于 repl 参数 re.sub here

以及正则表达式的解释:

(?s)        # the . matches newlines 
(?=<table)  # positive look-ahead matching '<table'
(.*)        # matches everything between <table and table> (it is inclusive because of the look-ahead/behinds)   
(?<=table>) # positive look-behind matching 'table>'

还要注意,因为(.*) 在捕获组中,所以它包含在re.split 输出的字符串中(参见here)

【讨论】:

  • 感谢您提供的编码示例 Bungi,它运行良好!我也很高兴通过查看您的代码学到了一些新东西,因为我对 Python(和一般编程)相对较新,学习如何应用新方法总是很棒。
【解决方案2】:

不要对自己太苛刻。我不确定是否可以使用标准 re sub 一次拍摄。事实上,我认为这要么不可能,要么非常复杂。例如替换中的自定义函数(您可以在自定义函数中填充很多自定义功能,最多可以使用整个 html 解析器)

相反,我强烈推荐一个简单的解决方案是使用 split/join 进行拆分和重新组装,或者,您可能会选择一系列重新替换。

假设一张桌子l = s.split('table&gt;'); l = [1] 会给你表格内容 和 l.split(。下面是一个多表版本

def curlyfy_el(s, tag='table'):

    return ('{%s' % tag).join(
                        [ ('{/%s}' % tag).join(
                                   [y if i != 0 else y.replace("<",  "{").replace(">", "}")
                                 for i, y in enumerate(x.split( '</%s>' % tag, 1)) 
    for x in s.split('<%s' % tag) ])

Sligty 更易读

def curlyfy_el(s, tag='table'):
    h, *t = s.split('<%s' % tag)  # stplit on some pretable text and fragments starting with table
    r = [h]
    for x in t:
        head, *tail = x.split('</%s>' % tag, 1)  # select table body and rest, 1 is to keep duplicate closure of tag in one str
        head = head.replace("<", "{")
        head = head.replace(">", "}")
        r.append( ('{/%s}' % tag).join([head, *tail]))
    return ('{/%s}' % tag).join(r)

一般处理HTML最好使用一些指定的解析库,比如beautiful soup,ad-hoc代码在很多极端情况下会失败。

【讨论】:

  • 嗨,Serge,感谢您的回复,我很感激。我尝试了您的方法,但是它很难使用,因为文件中可能有任意数量的表,并且在使用可能具有任意数量值的列表时,它开始与我的其余编码变得混乱。我敢肯定,如果我有更多的经验,我可以让它发挥作用,但我还没有完全做到。
  • 增强了多表数组
【解决方案3】:

您可以使用以下正则表达式进行匹配,然后替换为Group 1:

[\s\S]*(<table[\s\S]*?</table>)[\s\S]*

这将匹配'&lt;table' 之前的所有内容,然后使用表格内容创建一个Group 1,然后匹配之后的所有内容。

替换为:

$1

这只会给你一个包含内容的表格。

【讨论】:

  • 嗨 Poul,我尝试了这种方法,但它并没有完全满足我的要求。我想用不同类型的标记替换每个表中的所有 HTML 标记,但保留每个表之外的所有 HTML 标记。不过,我很感谢您的回复!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 2016-07-01
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多