所以,我想将此文本分为句子。
s = "You! Are you Tom? I am Danny."
所以我得到:
["You!", "Are you Tom?", "I am Danny."]
那就是我想在不删除定界数的情况下将文本拆分为Regex '[.!?]'
。在Python中实现这一目标的最高方法是什么?
我知道以下问题:
js string.split((而无需删除定界器
python split((不删除定界线
,但是我的问题有各种定系数(.?!
(,这使问题复杂化。
您可以将re.findall
与Regex .*?[.!?]
一起使用;懒惰量词*?
确保每个模式都与您要匹配的特定定界符匹配:
import re
s = """You! Are you Tom? I am Danny."""
re.findall('.*?[.!?]', s)
# ['You!', ' Are you Tom?', ' I am Danny.']
严格来说,您不想在'!?。'上拆分,而是在跟随这些字符的空格上。以下将有效:
>>> import re
>>> re.split(r'(?<=[.!?])s*', s)
['You!', 'Are you Tom?', 'I am Danny.']
这将在空格上分裂,但前提是在之前是a。,!或?字符。
如果python支持由零长度匹配分配,则可以通过匹配的一个空字符串之前,先于其中一个定界符:
(?<=[.!?])
演示:https://regex101.com/r/zldxr1/1
不幸的是,Python不支持零长度匹配分配。然而,该解决方案仍可能在支持lookhinds的其他语言中有用。
但是,基于您的输入/输出数据样本,您宁愿在一个定界符之前按空格分开。因此,正则是:
(?<=[.!?])s+
演示:https://regex101.com/r/zldxr1/2
python演示:https://ideone.com/z6nzi5
如果空间是可选的,我相信@psidom建议的re.findall
解决方案是最好的。
如果您喜欢使用拆分方法而不是匹配,则用组
拆分一个解决方案splitted = filter(None, re.split( r'(.*?[.!?])', s))
滤波器如果有的话,将卸下空字符串。
即使句子之间没有空格,或者您需要以不同的标点符号结尾,例如Unicode Ellipses(或完全有任何句子(
,这将起作用。甚至有可能保持您的re(逃避更正和添加括号(。
splitted = filter(None, re.split( r'([.!?])', s))
然后合并均匀,不均匀元素并删除额外的空间
python split((而无需删除定界线
最简单的方法是使用nltk
。
import nltk
nltk.sent_tokenize(s)
它将返回所有句子的列表,而不会失去定界者。