Python正则表达式为字符串中的所有单词添加字符,除了“and”
我想用 '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在评论中提到的。