在字符串中查找数字并将其递减

Find numbers in a string and decrement them

我有一个 HTML 页面,其中列出了很长的主题索引和页码。我想找到所有页码及其锚标记链接并将页码减少 1

这是 HTML 中的示例行:

<p class="index">breakeven volume (BEV), <a href="ch02.xhtml#page28">28</a></p>

我试图在两个地方找到数字 28 并减少 1

到目前为止,我已经能够找到该数字并将其替换为自身,但我不知道如何减少它。到目前为止我的代码:

import fileinput
import re

for line in fileinput.input():
    line = re.sub(r'\>([0-9]+)\<', r'><', line.rstrip())
    print(line)

请注意,您可以将 函数 作为 repl 参数传递给 re.sub,它将传递单个 match 对象 "for every non-overlapping occurrence of pattern":

def decrement(match):
    """Decrement the number in the match."""
    return str(int(match.group()) - 1)

请注意,这需要 match.group() 表示一个整数;要仅捕获数字,而不包括 ><,请使用环视(请参阅 demo):

page_num = re.compile(r'''
    (?<=>) # a > before the group
    \d+    # followed by one or more digits
    (?=<)  # and a < after the group
''', re.VERBOSE)

这符合您的要求:

>>> page_num.sub(decrement, line)
'<p class="index">breakeven volume (BEV), <a href="ch02.xhtml#page28">27</a></p>'

并且可以类似地应用于 '#page28"'

但是,请注意,您通常应该使用 实际的 HTML 解析器 ,而不是正则表达式来解析 HTML(不是一种常规语言)。

替换时可以使用替换函数:

import re
s = '<p class="index">breakeven volume (BEV), <a href="ch02.xhtml#page28">28</a></p>'
re.sub(r'page(\d+)">', lambda m: 'page{0}">{0}'.format(int(m.group(1)) - 1), s)

结果:

<p class="index">breakeven volume (BEV), <a href="ch02.xhtml#page27">27</a></p>

page(\d+)"> 匹配 page 后跟一个数字,然后是 ">,后跟相同的数字如第一对括号中的模式 (</code>).</p> <p>替换函数将匹配项作为参数。所以我们取匹配的第一组(<code>m.group(1)),也就是数字,我们解析它并递减它。然后我们使用递减后的数字重建新字符串。