Python正则表达式为字符串中的所有单词添加字符,除了“and”

2 投票
3 回答
1765 浏览
提问于 2025-04-18 22:07

我想用 'foo, bar and bee' 这个字符串生成 'foos, bars and bees'。我想用 re.sub 来实现这个功能。

我连给每个单词后面加个 's' 都搞不定。等我把这个部分弄明白了,再来处理 'and' 这个词的排除。我试过用 \b 加上 "s",但这样会匹配到单词的开头和结尾。如果我用 '\w*\b',那整个单词就会被替换掉。我正在查阅 Python 的文档,觉得 (?P)(?<=...) 这种回溯的写法可能是我需要的,但我在使用这些的时候遇到了麻烦,而且相关的例子也不多。

3 个回答

2

不考虑需要排除的词,下面的代码会在字符串中所有单词的末尾加上一个's':

re.sub('([a-zA-Z]+)','\\1s','foo, bar and bee')
-> 'foos, bars ands bees'

如果你想更通用、更少出错地处理单词的复数形式,可以看看这个inflect包(至少对于英语来说)。

3

下面的代码会在所有单词后面加上字母 s,除了单词 and 以外。

>>> import re
>>> s = "foo, bar and bee "
>>> m = re.sub(r'(?!and)(\b\w+\b)', r'\1s', s)
>>> m
'foos, bars and bees '

负向前瞻的意思是,它会匹配一个或多个字母,但不会匹配 \band\b。这里的 \b 是指单词边界,它用来区分字母和非字母的地方。

4

这个方法是基于替换功能可以接受一个可调用对象(也就是可以被调用的东西)来实现的:

re.sub('(\w+)', lambda m: m.group(1) + 's' if m.group(1) != 'and' else 'and', 'foo, bar and bee')

这个想法来源于一个旧的错误报告(倒数第二条记录)。

编辑:这里有一个更简短、可能更易读的解决方案:

re.sub('(and)|(\w+)', lambda m: m.group(1) or m.group(2) + 's', 'foo, bar and bee')

这个方法还有一个好处,就是更容易添加其他需要排除的单词,正如isedev在评论中提到的。

撰写回答