首页 > 解决方案 > 使用正则表达式查找和替换每个匹配项的任意数量的元素

问题描述

我的目标是识别标记语言中的粗体括号文本,例如:

[B] blah blah (foo) blah [/B]

并使用正则表达式用另一个标签包围它,如下所示:

[B] blah blah [C](foo)[/C] blah [/B]

这是我使用 Python 进行的尝试:

outtext = re.sub(r'(\[B\].*?)(\(.*?\))(.*?\[/B\])', r'\1[C]\2[/C]\3', intext)

问题是,如果块中有多个带括号的字符串,它就不起作用:

Input: [B] (foo) (bar) [/B]
Expected: [B] [C](foo)[/C] [C](bar)[/C] [/B]
Actual: [B] [C](foo)[/C] (bar) [/B]

我知道发生这种情况的原因,但我不知道如何解决。是否可以更改我的正则表达式,使其能够在每个块中查找和替换任意数量的带括号的字符串,而不仅仅是一个?

标签: pythonregex

解决方案


首先,我认为单独的正则表达式无法解决问题。JvdV 证明这是错误的,做得很好。老实说,我不再理解这个正则表达式了。

我用一些更简单的正则表达式和一些 python 解决了它

import re

intext = '[B] (foo) (bar) [/B] (not) [B] (this again) [/B]'

boldParts = re.findall(r'\[B\].*?\[/B\]', intext)
outtext = intext
for part in boldParts:
    replacement = re.sub(r'(\(.*?\))', r'[C]\1[/C]', part)
    outtext = outtext.replace(part, replacement)

print(outtext)

首先,我只查找文本中的粗体部分,然后很容易替换括号中的内容。并再次在 outtext 中替换它。

诚然,这不是最短或最优雅的方式,但可能更具可读性。


推荐阅读