Python - 用于将文本拆分为句子的RegEx(句子标记化)

use*_*149 22 python regex nlp tokenize

我想从一个字符串中创建一个句子列表然后将它们打印出来.我不想用NLTK来做这件事.因此,它需要在句子末尾的句点分割,而不是在小数,缩写或名称的标题上,或者如果句子有.com这是尝试正则表达式不起作用.

import re

text = """\
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't.
"""
sentences = re.split(r' *[\.\?!][\'"\)\]]* *', text)

for stuff in sentences:
        print(stuff)    
Run Code Online (Sandbox Code Playgroud)

示例输出的示例

Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. 
Did he mind?
Adam Jones Jr. thinks he didn't.
In any case, this isn't true...
Well, with a probability of .9 it isn't.
Run Code Online (Sandbox Code Playgroud)

vks*_*vks 31

(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s
Run Code Online (Sandbox Code Playgroud)

试试这个.拆分你的字符串.你也可以查看演示.

http://regex101.com/r/nG1gU7/27

  • 我将其扩展为 `(?&lt;!\w\.\w.)(?&lt;![AZ][az]\.)(?&lt;=\.|\?|\!\:)\s+|\p {Cc}+|\p{Cf}+` 也考虑不可见字符。 (2认同)

smc*_*mci 27

好的,所以我使用正则表达式,nltk,CoreNLP来详细查看了句子标记符.你最终编写自己的,这取决于应用程序.这些东西很棘手且很有价值,而且人们不只是将其令牌化代码放弃.(最终,标记化不是一个确定性的过程,它是概率性的,并且还非常依赖于您的语料库或域,例如社交媒体帖子与Yelp评论vs ...)

一般来说,你不能依赖一个单一的Great White绝对可靠的正则表达式,你必须编写一个使用几个正则数据(正面和负面)的函数; 还有一个缩写词典,以及一些基本的语言解析,它们知道例如"我","美国","FCC","TARP"都是用英语大写的.

为了说明这是多么容易变得非常复杂,让我们试着写一个确定性标记化器的功能规范,只是为了决定单个或多个句点('.'/'...')是否表示句末,或者某事其他:

function isEndOfSentence(leftContext, rightContext)

  1. 数字或货币内的小数返回False,例如1.23,$ 1.23,"那只是我的$ .02"还要考虑1.2.3之类的章节引用,09.07.2014等欧洲日期格式,192.168.1.1等IP地址,MAC地址......
  2. 对于已知缩写,例如"美国股市正在下跌",则返回False(并且不会将其标记为单个字母); 这需要已知缩写词典.除非你添加代码来检测像ABC这样的未知缩写并将它们添加到列表中,否则除了字典之外的任何内容都会出错.
  3. 句子末尾的省略号'...'是终点,但句子中间没有.这并不像你想象的那么容易:你需要查看左上下文和正确的上下文,特别是RHS大写,并再次考虑大写单词,如'I'和缩写.这是一个证明含糊不清的例子:她让我留下......我离开一小时后.(那是一句还是两句?无法确定)
  4. 您可能还想编写一些模式来检测和拒绝标点符号的各种非句子结尾使用:表情符号:-),ASCII艺术,间隔椭圆...和其他东西,尤其是 推特.(使适应​​性变得更加困难).我们如何判断@midnight是Twitter用户,Comedy Central上的节目,文本速记,还是简单的垃圾/垃圾/错字标点符号?严重不平凡.
  5. 处理完所有这些否定案件后,您可以随意说任何孤立的句子后面跟空格可能是句末.(最终,如果你真的想要购买额外的准确性,你最终会编写自己的概率句 - 标记器,它使用权重,并在特定的语料库上进行训练(例如法律文本,广播媒体,StackOverflow,Twitter,论坛评论等) )然后你必须手动审查样本和训练错误.参见Manning和Jurafsky的书或Coursera课程[a].最终,你会得到你准备支付的正确性.
  6. 以上所有内容都明确针对英语/缩写,美国数字/时间/日期格式.如果你想让它独立于国家和语言,这是一个更大的命题,你需要语料库,母语人士来标记和QA这一切,等等.
  7. 以上所有内容仍然只是ASCII.允许输入为Unicode,事情变得更难(并且训练集必须要么大得多或者更稀疏)

在简单(确定性)的情况下,function isEndOfSentence(leftContext, rightContext)将返回布尔值,但在更一般意义上,它是概率性的:它返回一个浮点数0.0-1.0(特定'.'是一个句子结束的置信度).

参考文献:[a] Coursera视频:"基本文本处理2-5 - 句子分割 - 斯坦福NLP - 丹·朱拉夫斯基教授和克里斯·曼宁" [更新:曾经在YouTube上的非官方版本被删除]


Avi*_*Raj 5

尝试根据空格而不是点或来分割输入?,如果您喜欢这样做,则点或?将不会打印在最终结果中。

>>> import re
>>> s = """Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it. Did he mind? Adam Jones Jr. thinks he didn't. In any case, this isn't true... Well, with a probability of .9 it isn't."""
>>> m = re.split(r'(?<=[^A-Z].[.?]) +(?=[A-Z])', s)
>>> for i in m:
...     print i
... 
Mr. Smith bought cheapsite.com for 1.5 million dollars, i.e. he paid a lot for it.
Did he mind?
Adam Jones Jr. thinks he didn't.
In any case, this isn't true...
Well, with a probability of .9 it isn't.
Run Code Online (Sandbox Code Playgroud)