Python:如何在re.sub()的替换参数中添加计数器?

3 投票
5 回答
1625 浏览
提问于 2025-04-30 21:43

我想给HTML标签添加一些ID。比如,我想把:

<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>

改成

<p id="1">First paragraph</p>
<p id="2">Second paragraph</p>
<p id="3">Third paragraph</p>

我记得可以用一个叫做lambda的函数来实现这个功能,但我不太记得具体的写法了。

暂无标签

5 个回答

0

使用 re.sub() 方法

x=['<p>First paragraph</p>', '<p>Second paragraph</p>', '<p>Third paragraph</p>']
for i, p in enumerate(x,start=1):
...     re.sub(r'^<p>', '<p id="%d">'%i, p)
... 
'<p id="1">First paragraph</p>'
'<p id="2">Second paragraph</p>'
'<p id="3">Third paragraph</p>'
1

我想补充一下@Michael0x2a的回答。

他的代码里有一个大问题,特别是:如果没有任何东西被替换,计数器仍然会返回1。还有一些小问题。

为了绕过这个主要的问题,可以使用快速的哈希算法。我会用Adler32。

import re
import zlib

class Replace(object):
    def __init__(self):
        self.counter = 0

    def __call__(self, match):
        self.counter += 1
        return '<p id="{0}">'.format(self.counter)

replace = Replace()
old = zlib.adler32(your_string)
replaced = re.sub(pattern, replace, your_string)
new = zlib.adler32(replaced)

if(old == new):
    replace.counter = 0
2

这个方法可能不是特别通用,但应该能用。

def sub_p(string):
   def inc(m, i=[0]):
      i[0] += 1
      return '<p id="%i">' % i[0]
   return re.sub(r"<p>", inc, string)
5

如果你想使用正则表达式,一个简单粗暴的办法就是用一个全局变量,像这样:

i = 0

def replace(match):
    global i
    i += 1
    return '<p id="{0}">'.format(i)

re.sub(pattern, replace, your_string)

另外,你也可以创建一个自定义的类,让它“假装”成一个函数,使用 __call__ 方法,并把计数器定义为一个字段:

class Replace(object):
    def __init__(self):
        self.counter = 0

    def __call__(self, match):
        self.counter += 1
        return '<p id="{0}">'.format(self.counter)

replace = Replace()
re.sub(pattern, replace, your_string)
7

我会使用一个HTML解析器,比如BeautifulSoup

这个想法是用enumerate()来遍历所有段落,并给它们编号,从1开始:

from bs4 import BeautifulSoup

data = """
<p>First paragraph</p>
<p>Second paragraph</p>
<p>Third paragraph</p>
"""

soup = BeautifulSoup(data, 'html.parser')
for index, p in enumerate(soup.find_all('p'), start=1):
    p['id'] = index

print soup

输出结果:

<p id="1">First paragraph</p>
<p id="2">Second paragraph</p>
<p id="3">Third paragraph</p>

撰写回答