【问题标题】:How to replace multiple regex matches in text block如何替换文本块中的多个正则表达式匹配
【发布时间】:2018-12-20 21:54:51
【问题描述】:

我正在尝试将段落中的多个匹配项转换为链接,同时在最终输出中保留周围的文本。我匹配的模式让人想起 Markdown 的超链接语法,作为一种允许非技术用户定义他们希望在输入中链接的文本的方式(我通过 Sheets API/Python 访问的 Google Sheet)。我捕获的第一组是链接文本,第二组是查询字符串中键的值。

我已经能够成功匹配此模式的单个实例,但我的替换字符串替换了输出中的整个段落。

text = "2018 was a big year for my sourdough starter and me. Mostly 
we worked on developing this [tangy bread](19928) and these [chewy 
rolls] (9843). But we were also just content keeping each other 
company and inspired to bake."

def link_inline(text):
    # expand a proper link around recipe id
    ref = re.search(r"(\[.*?\]\(\d+\))", text, re.MULTILINE).group(1)
    if (len(ref) > 0):
        link = re.sub("\[(.*?)\]\((\d+)\)", r"<a href='https://www.foo.com/recipes?rid=\2'>\1</a>", ref)
        return text
    else:
        return "replacement failed"

目标是让此输出保持段落完整,并简单地将 \[(.*?)\]\((\d+)\) 模式匹配替换为以下字符串,包括组的反向引用:&lt;a href="https://www.foo.com?bar=\2"&gt;\1&lt;/a&gt;

所以它需要遍历文本来替换所有匹配项(大概是re.finditer?),并且还要在模式匹配之外维护原始文本。但我不确定如何正确定义循环并执行此替换,而不用我的替换字符串覆盖整个段落。

【问题讨论】:

  • 字符串无法更改。那里的变量只能重新赋值。

标签: python regex


【解决方案1】:

我使用了re.compile,而不是在整个组中放置括号,而是在.*? 周围放置一对,在\d+ 周围放置另一对,因为这两个部分代表我们要提取和放置的文本进入我们的网址。

import re

def link_inline(text):
    # expand a proper link around recipe id
    ref = re.compile("\[(.*?)\]\((\d+)\)")
    replacer = r'<a href="https://www.foo.com/recipes?rid=\2">\1</a>'
    return ref.sub(replacer, text)


text = """
2018 was a big year for my sourdough starter and me. Mostly we worked on
 developing this [tangy bread](19928) and
 these [chewy rolls](9843). But we were also just
 content keeping each other company and inspired to bake.
"""

print(link_inline(text))

输出:

2018 was a big year for my sourdough starter and me. Mostly we worked on
 developing this <a href="https://www.foo.com/recipes?rid=19928">tangy bread</a> and
 these <a href="https://www.foo.com/recipes?rid=9843">chewy rolls</a>. But we were also just
 content keeping each other company and inspired to bake.

作为健全性检查,我尝试在字符串text 中添加一些带括号和方括号的额外字符串,例如(this) here[this] here。一切仍然正常。

【讨论】:

  • 我还可以使用re.findall 来生成匹配数组,然后使用与原始帖子中相同的re.sub 函数添加一个for 循环。但是,您使用re.compile 的方法似乎要简单得多。为什么不需要循环?
猜你喜欢
  • 2016-03-14
  • 2012-09-28
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多