如何在Python中使用re.sub()正确迭代

Ala*_*lan 10 python regex

我想制作一个创建脚注的Python脚本.我们的想法是找到所有类型的字符串"Some body text.{^}{Some footnote text.}"并替换它们"Some body text.^#",其中"^#"是正确的脚注编号.(我的脚本的另一部分涉及实际打印文件底部的脚注.)我正在使用的当前代码是:

pattern = r"\{\^\}\{(.*?)\}"
i = 0
def create_footnote_numbers(match):
   global i
   i += 1
   return "<sup>"+str(i)+"</sup>"

new_body_text = re.sub(pattern, create_footnote_numbers, text)
Run Code Online (Sandbox Code Playgroud)

这很好,但是icreate_footnote_numbers函数外部声明一个变量()然后必须在该函数内调用它似乎很奇怪.我原本以为里面会有一些东西re会返回比赛的数量.

Mar*_*ers 12

可以使用任何可调用的,因此您可以使用类来跟踪编号:

class FootnoteNumbers(object):
    def __init__(self, start=1):
        self.count = start - 1

    def __call__(self, match):
        self.count += 1
        return "<sup>{}</sup>".format(self.count)


new_body_text = re.sub(pattern, FootnoteNumbers(), text)
Run Code Online (Sandbox Code Playgroud)

现在,计数器状态包含在FootnoteNumbers()实例中,并且self.count每次开始re.sub()运行时都会重新设置.


jfs*_*jfs 6

它似乎非常适合闭合:

def make_footnote_counter(start=1):
    count = [start - 1] # emulate nonlocal keyword
    def footnote_counter(match):
        count[0] += 1
        return "<sup>%d</sup>" % count[0]
    return footnote_counter

new_body_text = re.sub(pattern, make_footnote_counter(), text)
Run Code Online (Sandbox Code Playgroud)