This is a CHINESE sentence cutting tool.
Project description
sentence-spliter
[toc]
1. 介绍
sentence-spliter 句子切分工具,将一个长的句子,切分为短句的 List 。支持自然切分,最长句切分,最短句合并。
目前支持语言:中文
2. 项目结构
└── sentence_spliter
├── __init__.py
├── automata
│ ├── __init__.py # 存放切句的基本单元
│ ├── abc.py # 定义状态机与图的基本单元
│ ├── condition.py # 切句条件
│ ├── operation.py # 切句操作
│ ├── sequence.py # 封装状态传递的数据
│ ├── state_machine.py # 状态机
│ └── symbols.py # 保存标点符号
├── logic_graph.py # 逻辑图
└── spliter.py # 主要函数,调用切句
3. Setup
PYPI 安装
pip install sentence-spliter
4. Demo
4.1. Simple Demo
from sentence_spliter.spliter import cut_to_sentences
# -- demo 1 -- #
paragraph = "在很久很久以前......。。... 有座山,山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。"
result = spliter.cut_to_sentences(paragraph)
print(result)
['在很久很久以前......。。...', ' 有座山,山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。']
# -- demo 2 -- #
paragraph = "求月票啊!求月票啊!求月票啊!~~~ 重要的事情说三遍!"
result = spliter.cut_to_sentences(paragraph)
print(result)
['求月票啊!', '求月票啊!', '求月票啊!~~~ ', ' 重要的事情说三遍!']
# -- demo 3 -- #
paragraph = "《啊!啊!啊!》是本耐人寻味的读物。"
result = spliter.cut_to_sentences(paragraph)
print(result)
['《啊!啊!啊!》是本耐人寻味的读物。']
切句支持以整片文章为输入。
如果输入太长,终端会自动显示百分比process cutting 87.5%
4.2. Demo in detail
切句工具默认有两种种逻辑
4.2.1. 自然切分
基本逻辑:
- 遇到断句标点(。?!)准备切句:
- 如果短句标点出现在
引号
、括号
、书名号
不执行切句- 其他情况下执行切句
自然切分可以通过调用cut_to_sentences
使用 (是cut_to_sentences
默认配置)
from sentence_spliter.spliter import cut_to_sentences
paragraph = "在很久很久以前......。。... 有座山,山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。"
result = spliter.cut_to_sentences(paragraph)
print(result)
['在很久很久以前......。。...', ' 有座山,山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。']
自然切分也可以通过调用logic_graph
和state_machine
- 优点,用户可以自己配置如何创建
state_machine
的实例
#导入逻辑
from sentence_spliter.logic_graph import simple_cuter
#导入状态机
from sentence_spliter.automata.state_machine import StateMachine
#导入序列,str 需要封装成StrSquence 喂给状态机
from sentence_spliter.automata.sequence import StrSequence
# -- 初始化 状态机器 -- #
cuter = StateMachine(simple_cuter())
# -- 处理句子 -- #
paragraph = "“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”“你知道么?CNN你们总是制造假新闻。。。”"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()
# -- 展示结果 -- #
print(out)
['“我和你讨论的不是一个东西,死亡率与死亡比例是不同的”', '“你知道么?CNN你们总是制造假新闻。。。”']
4.2.2. 长短处理切句
基本逻辑:
- 如果是短句:则该句子与右边句子合并
- 如果是长句:
- 优先基于断句标点做二次切句
- 再基于
逗号
做二次切句
需要参数:
- hard_max (默认300): 最大可接受长度,要保证所有句子(除了最后一句)<= hard_max
- max_len (默认128): 长句判断条件,如果句子大于 max_len则为长句
- max_len 可以等于 hard_max
- min_len (默认15): 短句判断条件,如果句子小于min_len则为短句
同样长短句处理切分可以通过调用cut_to_sentences
使用 (但是长短句参数均为默认且不可调整)
from sentence_spliter import spliter
# -- 使用长短句切句 -- #
paragraph = "求月票啊!求月票啊!求月票啊!~~~ 重要的事情说三遍!"
result = spliter.cut_to_sentences(paragraph, long_short=True)
print(result)
['求月票啊!求月票啊!求月票啊!~~~ ', ' 重要的事情说三遍!']
# -- 不使用长短句切句 -- #
paragraph = "求月票啊!求月票啊!求月票啊!~~~ 重要的事情说三遍!"
result = spliter.cut_to_sentences(paragraph, long_short=False)
print(result)
['求月票啊!', '求月票啊!', '求月票啊!~~~ ', ' 重要的事情说三遍!']
长短句切分也可以通过调用logic_graph
和state_machine
- 优点
- 用户可以自己配置如何创建
state_machine
的实例 - 用户可以自定义参数
- 用户可以自己配置如何创建
from sentence_spliter.logic_graph import long_short_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence
# -- 初始化 状态机器 -- #
cuter = StateMachine(long_short_cuter(hard_max = 128, max_len= 128, min_len = 15))
# -- 处理句子 -- #
paragraph = "在很久很久以前1.2.3......。。... 有座山。山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。www.baidu.com"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()
# -- 展示结果 -- #
print(out)
['在很久很久以前1.2.3......。。...', ' 有座山。山里有座庙啊!!!!!!!', '庙里竟然有个老和尚!?。。。。', 'www.baidu.com']
from sentence_spliter.logic_graph import long_short_cuter
from automata.state_machine import StateMachine
from automata.sequence import StrSequence
# -- 初始化 状态机器 -- #
cuter = StateMachine(long_short_cuter(hard_max = 2, max_len= 2, min_len = 1))
# -- 处理句子 -- #
paragraph = "在很久很久以前1.2.3......。。... 有座山。山里有座庙啊!!!!!!!庙里竟然有个老和尚!?。。。。www.baidu.com"
sequence = cuter.run(StrSequence(paragraph))
out = sequence.sentence_list()
# -- 展示结果 -- #
print(out)
['在很', '久很', '久以', '前1', '.2', '.3', '..', '..', '..', '。。', '..', '.', ' 有', '座山', '。', '山里', '有座', '庙啊', '!!', '!!', '!!', '!', '庙里', '竟然', '有个', '老和', '尚!', '?。', '。。', '。', 'ww', 'w.', 'ba', 'id', 'u.', 'com']
5. 自定义规则
切句规则都是基于图来实现的,其中
automata/condition.py
存放图的边automata/operation.py
存放节点
5.1. 定义一个简单的切句规则
规则如下:
- 如果遇到断句标点 执行切句
代码:
from automata import condition, operation
from automata.state_machine import StateMachine
from automata.sequence import StrSequence
# step 1: 初始所以需要的边和节点
edges = {
'is_end_symbol': condition.IsEndSymbol(),
'is_end_state': condition.IsEndState(),
}
nodes = {
'init': operation.Indolent(),
'do_cut': operation.Normal(),
'end': operation.EndState()
}
# step 2: 构建图
simple_logic = {
nodes['init']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': edges['is_end_symbol'],
'node': nodes['do_cut']}
],
nodes['do_cut']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': None,
'node': nodes['init']} # else 状态
],
}
# step 3: 初始化状态机
machine = StateMachine(simple_logic)
# step 4: 切句测试
sentences = '万壑树参天,千山响杜鹃。山中一夜雨,树杪百重泉。汉女输橦布,巴人讼芋田。文翁翻教授,不敢倚先贤。'
out = machine.run(StrSequence(sentences))
print('\n'.join(out.sentence_list()))
输出:
万壑树参天,千山响杜鹃。
山中一夜雨,树杪百重泉。
汉女输橦布,巴人讼芋田。
文翁翻教授,不敢倚先贤。
注意:
- machine 是从 Indolent状态开始便利,遍历顺序从上倒下
- 每个状态必须先有end_state条件否则报错
5.2. 多条边都指向一个节点
考虑以下两个规则:
规则一
- 如果遇到切句标点同时出现在书名号外面,则切句
规则二
- 如果遇到切句标点或者 右引号,则切句
我们可以在边中使用list
方法来实现and
和or
from sentence_spliter.automata import condition, operation
from sentence_spliter.automata.state_machine import StateMachine
from sentence_spliter.automata.sequence import StrSequence
# step 1: 初始所以需要的边和节点
edges = {
'is_end_symbol': condition.IsEndSymbol(),
'is_end_state': condition.IsEndState(),
'is_book_symbol': condition.IsBookClose(),
'is_left_quota': condition.IsLeftQuota()
}
nodes = {
'init': operation.Indolent(),
'do_cut': operation.Normal(),
'end': operation.EndState()
}
# step 2: 构建图
simple_logic = {
nodes['init']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': [edges['is_end_symbol'],
edges['is_book_symbol']],
'args': all, # 我们使用arg 来填 or 或者 and
'node': nodes['do_cut']}
],
nodes['do_cut']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': None,
'node': nodes['init']} # else 状态
],
}
# step 3: 初始化状态机
machine = StateMachine(simple_logic)
# step 4: 切句测试
sentences = '《啊!啊!啊!》是本耐人寻味的读物。'
out = machine.run(StrSequence(sentences))
print('\n'.join(out.sentence_list()))
输出
《啊!啊!啊!》是本耐人寻味的读物。
表示or
from sentence_spliter.automata import condition, operation
from sentence_spliter.automata.state_machine import StateMachine
from sentence_spliter.automata.sequence import StrSequence
# step 1: 初始所以需要的边和节点
edges = {
'is_end_symbol': condition.IsEndSymbol(),
'is_end_state': condition.IsEndState(),
'is_book_symbol': condition.IsBookClose(),
'is_right_quota': condition.IsRightQuota()
}
nodes = {
'init': operation.Indolent(),
'do_cut': operation.Normal(),
'end': operation.EndState()
}
# step 2: 构建图
simple_logic = {
nodes['init']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': [edges['is_end_symbol'],
edges['is_right_quota']],
'args': any,
'node': nodes['do_cut']}
],
nodes['do_cut']: [
{'edge': edges['is_end_state'],
'node': nodes['end']},
{'edge': None,
'node': nodes['init']} # else 状态
],
}
# step 3: 初始化状态机
machine = StateMachine(simple_logic)
# step 4: 切句测试
sentences = '“时代变了~”,小明感叹道。'
out = machine.run(StrSequence(sentences))
print('\n'.join(out.sentence_list()))
输出
“时代变了~”
,小明感叹道。
5.3. 自定义节点和边
- 节点要保证输入和输出都是
sequece.StrSequence
就可以放在状态机中运行 - 边要保证输入是
sequece.StrSequence
输出是bool
就可以放在状态机中运行
这里不再做演示
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
sentence-spliter-1.0.4.tar.gz
(15.7 kB
view hashes)
Built Distribution
Close
Hashes for sentence_spliter-1.0.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | df69cb8ba31ae6b4313abb61e8186ddeba1014628de8d6f5952bc71ed2b70fc8 |
|
MD5 | a368215a8842c30b97a167ab48fcfd54 |
|
BLAKE2b-256 | 13875f9ca52f21d3c357d0f4259d9016a5b2c230856de5c1e34160ed97d2c5d9 |