为与字符串中某个正则表达式匹配的数字加一

Had*_*obi 5 python regex

我有一个看起来像这样的 Python 字符串:

"5 pounds cauliflower,
cut into 1-inch florets (about 18 cups)
2 large leeks,
1 teaspoons salt
3 cups of milk"
Run Code Online (Sandbox Code Playgroud)

我需要为关键字之前出现的每个数字加 1 cup

结果需要是:

"5 pounds cauliflower,
cut into 1-inch florets (about 19 cups)
2 large leeks,
1 teaspoons salt
4 cups of milk"
Run Code Online (Sandbox Code Playgroud)

我有一些类似的事情:

import re

p = re.compile('([0-9]+) cup')
for i in p.finditer(s):
    # do something with int(i.group(1)) + 1
Run Code Online (Sandbox Code Playgroud)

我不知道如何仅替换我在每次迭代中找到的数字。

我还有一种边缘情况,我可能需要将 9 替换为 10,因此我不能简单地获取数字的索引并将该数字替换为新数字,因为新数字可能会更长。

不涉及正则表达式的解决方案也受到欢迎。

Hal*_*Ali 7

您可以将函数作为替换字符串传递给函数sub。该函数接收一个匹配对象作为参数。

处理接收到的参数以为每个匹配创建替换字符串。

感谢 @ctwheels 的回答,我改进了最初的正则表达式处理。

mystring = """
5 pounds cauliflower,
cut into 1-inch florets (about 19 cups)
2 large leeks,
1 teaspoons salt
4 cups of milk
"""

p = r'\d+(?= +cups?\b)'

newstring = re.sub(p, lambda x: str(int(x.group(0))+1), mystring)

print(newstring)

# outputs:
5 pounds cauliflower,
cut into 1-inch florets (about 20 cups)
2 large leeks,
1 teaspoons salt
5 cups of milk
Run Code Online (Sandbox Code Playgroud)

为了处理单词复数(正如 @CasimiretHippolyte 所要求的),我们可以使用更广泛的模式,但稍微复杂一些的替换函数:

def repl(x):
    d = int(x.group(0).split()[0]) + 1
    return str(d) + ' cup' if d == 1 else str(d) + ' cups'

p = r'\d+ cups?'


mystring = """
5 pounds cauliflower,
cut into 1-inch florets (about 19 cups)
2 large leeks,
1 teaspoons salt
4 cups of milk
1 cup of butter
0 cups of sugar"""


newstring = re.sub(p, repl, mystring)
print(newstring)
# outputs
5 pounds cauliflower,
cut into 1-inch florets (about 20 cups)
2 large leeks,
1 teaspoons salt
5 cups of milk
2 cups of butter
1 cup of sugar
Run Code Online (Sandbox Code Playgroud)