根据标点或驼峰命名分割句子
我在Python中有一个很长的字符串,想把它分成一个句子的列表。不过,有些句子之间缺少标点符号和空格。
举个例子
我车库里有9只羊视频游戏超级酷。
我搞不清楚怎么用正则表达式把这两个句子分开!这让我很头疼。
还有一些句子是有正确标点的,所以我想做几个不同的正则表达式,每个用来分开不同风格的组合。
输入
我车库里有9只羊视频游戏超级酷。有些花生会唱歌,虽然它们的味道比听起来好得多!
输出
['我车库里有9只羊', '视频游戏超级酷。', '有些花生会唱歌,虽然它们的味道比听起来好得多!']
谢谢!
1 个回答
3
位置拆分:使用 regex
模块
我会给你提供一个“拆分”和一个“匹配所有”的选项。我们先从“拆分”开始。
在很多引擎中,但不是Python的 re
模块,你可以在一个零宽匹配的位置进行拆分。
在Python中,如果要在某个位置拆分,我会使用Matthew Barnett的优秀regex
模块,它的功能远远超过Python默认的 re
引擎。这个模块是我在Python中使用的默认正则表达式引擎。
根据你的输入,你可以使用这个正则表达式:
(?V1)(?<=[a-z])(?=[A-Z])|(?<=[.!?]) +(?=[A-Z])
注意,如果你有格式奇怪的缩写,比如 B. B. C.
,我们需要对这个表达式进行调整。
示例Python代码:
string = "I have 9 sheep in my garageVideo games are super cool. Some peanuts can sing, though they taste a whole lot better than they sound!"
result = regex.split("(?V1)(?<=[a-z])(?=[A-Z])|(?<=[.!?]) +(?=[A-Z])", string)
print(result)
输出:
['I have 9 sheep in my garage',
'Video games are super cool.',
'Some peanuts can sing, though they taste a whole lot better than they sound!']
解释
(?V1)
告诉引擎使用新的行为,这样我们就可以在零宽匹配的位置进行拆分。(?<=[a-z])(?=[A-Z])
匹配一个位置,在这个位置,前面是小写字母,后面是大写字母。|
或者...(?<=[.!?]) +(?=[A-Z])
匹配一个或多个空格+
,在这个位置,前面是句号、感叹号或问号和一个空格,后面是一个大写字母。
选项2:使用 findall
(同样使用 regex
模块)
因为“拆分”和“匹配所有”操作是同一个问题的两个方面,你可以这样做:
print(regex.findall(r".+?(?:(?<=[.!?])|(?<=[a-z])(?=[A-Z]))",string))
再次强调,这在 re
中是无法实现的(因为它会跳过第二个句子开头的 V
,也就是 Video
)。