Python实现对中文文本分段分句

作者:虚坏叔叔 时间:2022-09-16 18:16:50 

一、问题

实现对文本的分句,大致来说主要是以中文的句号、感叹、问号等符号进行分句。难点在于直接分句可能会造成人物说话的语句也被分开!

二、步骤

分段

首先读取文本,文本读取后整体是一个字符串,每一个段之间是空白,所以分段之间按照空白分开来即可,最后存入一个paragraph_list,注意该list的下标就是段落的顺序号!其他的这里就不再多赘述!(可以查看最后的整体代码)

分句

首先拿到上面分好的paragraph_list,循环拿到每一段,然后对每一段直接按照分句规则(正则表达式)进行分句,参考该文章

import re

def cut_sent(para):
   para = re.sub('([。!?\?])([^”'])', r"\1\n\2", para)
   para = re.sub('(\.{6})([^”'])', r"\1\n\2", para)
   para = re.sub('(\…{2})([^”'])', r"\1\n\2", para)
   para = re.sub('([。!?\?][”'])([^,。!?\?])', r'\1\n\2', para)
   para = para.rstrip()
   return para.split("\n")

# 这一段文字分句后应该有的结果
s = '今天天气好啊!' \
   '温度高吗?你好,很高兴遇见你,真不错。' \
   '小明遇见小红说:"你的衣服这好看!"' \
   '小红说:"什么?衣服真好看?真的吗?"' \
   '小明回答到:"嗯,真的!我也想买。"'

for i in cut_sent(s):
   print(i)

#结果将人物语句也分开
"""
今天天气好啊!
温度高吗?
你好,很高兴遇见你,真不错。
小明遇见小红说:"你的衣服这好看!
"小红说:"什么?
衣服真好看?
真的吗?
"小明回答到:"嗯,真的!
我也想买。
"
"""

连接

这里解决办法就是循环每一句,识别:"和"

  • 两个符号均有,则该句直接就是一整句,直接就加入

  • 两个符号都没有,则该句直接就是一整句,直接就加入

  • 如果只有前面符号而无后面符号,则记录有前面符号那一句,依次往下拼接,直到遇到字符最后有“,将上面拼接好的语句作为一整句放入

def connect(paragraph):
   sentence_before = []
   sentence_after = []
   for each_para in paragraph:
       sentence_before.append(cut(each_para))
   # 核心代码!(将被错分的语句进行连接)
   for each in sentence_before:
       list = []
       sentence = ""
       FLAG = True # 非常关键!判断有':“'的符号后面的语句是否继续拼接
       for i in each:
           if i.find(':“') * i.find('”') >= 0 and FLAG:
               list.append(i + sentence)
           else:
               FLAG = False
               sentence = sentence + i
               if i.find('”') > 0:
                   list.append(sentence)
                   sentence = ""
                   FLAG = True
       sentence_after.append(list)
   return sentence_after

三、最后整体代码

import re
import pandas as pd

# 将整篇文章进行分段
def segments(url):
   raw = pd.read_csv(url,names=['txt'], sep='aaa', encoding="GBK" ,engine='python')

def m_head(tem_str):
       return tem_str[:1]

def m_mid(tmp_str):
       return tmp_str.find("回 ")
   raw['head'] = raw.txt.apply(m_head)
   raw['mid'] = raw.txt.apply(m_mid)
   raw['len'] = raw.txt.apply(len)
   chap_num = 0
   for i in range(len(raw)):
       if raw['head'][i] == "第" and raw['mid'][i] > 0 and raw['len'][i] < 30:
           chap_num += 1
       if chap_num >= 40 and raw['txt'][i] == "附录一:成吉思汗家族":
           chap_num = 0
       raw.loc[i, 'chap'] = chap_num
   del raw['head']
   del raw['mid']
   del raw['len']
   tmp_chap = raw[raw['chap'] == 7].copy()
   tmp_chap.reset_index(drop=True, inplace=True)
   tmp_chap['paraidx'] = tmp_chap.index
   paragraph = tmp_chap['txt'].values.tolist()
   return paragraph

# 将每段进行分句
def cut(para):
   # 相关规则
   pattern = ['([。!?\?])([^”'])','(\.{6})([^”'])','(\…{2})([^”'])','([。!?\?][”'])([^,。!?\?])']
   for i in pattern:
       para = re.sub(i, r"\1\n\2", para)
   para = para.rstrip()
   return para.split("\n")

# 将其中被错分的语句进行连接(主要是针对话语)
def connect(paragraph):
   sentence_before = []
   sentence_after = []
   for each_para in paragraph:
       sentence_before.append(cut(each_para))
   # 核心代码!(将被错分的语句进行连接)
   for each in sentence_before:
       list = []
       sentence = ""
       FLAG = True # 非常关键!判断有':“'的符号后面的语句是否继续拼接
       for i in each:
           if i.find(':“') * i.find('”') >= 0 and FLAG:
               list.append(i + sentence)
           else:
               FLAG = False
               sentence = sentence + i
               if i.find('”') > 0:
                   list.append(sentence)
                   sentence = ""
                   FLAG = True
       sentence_after.append(list)
   return sentence_after

# 将最后的结果保存到DataFrame
def toDataFrame(list3):
   df = pd.DataFrame(columns=["content","paragraph","sentence"])
   for para_num,i in enumerate(list3):
      for sentence_num,j in enumerate(i):
           df_ = pd.DataFrame({"content": j, "paragraph": para_num,"sentence":sentence_num+1},index=[para_num])
           df = df.append(df_,ignore_index=True)
   for i in df['content'].values.tolist():
       print(i)

def main():
   # URL = "/Users/dengzhao/Downloads/金庸-射雕英雄传txt精校版.txt"
   URL = input("请输入文件地址:")
   para = segments(URL)
   result = connect(para)
   print(result)
   flag = input("以DataFrame形式输出数据(Y,N):")
   if flag == 'Y':
       toDataFrame(result)
   elif flag == 'N':
       print("Thanks!!!!")
   else:
       print("程序结束!请检查的你的输入!")

if __name__ == '__main__':
   main()

来源:https://blog.csdn.net/biggbang/article/details/129535678

标签:Python,文本,分段,分句
0
投稿

猜你喜欢

  • Python实现企业微信通知机器人的方法详解

    2021-03-12 09:56:02
  • python过滤中英文标点符号的实例代码

    2022-11-09 13:43:09
  • Python编程OpenCV和Numpy图像处理库实现图片去水印

    2023-10-10 15:12:44
  • 七种PHP开发环境搭建工具

    2023-10-25 13:47:48
  • python微信好友数据分析详解

    2022-01-27 20:36:39
  • xhtml+css VS div+css

    2008-04-07 13:00:00
  • 以SQLite和PySqlite为例来学习Python DB API

    2023-07-13 02:19:14
  • Django rest framework分页接口实现原理解析

    2023-08-22 21:26:36
  • 使用标准的表单字段名

    2008-06-30 14:14:00
  • python获取酷狗音乐top500的下载地址 MP3格式

    2021-05-06 04:38:05
  • WAP中的ASP技术

    2008-05-18 13:30:00
  • sqlserver 快速生成汉字的首拼字母的函数(经典)

    2012-06-06 20:16:41
  • python基础之错误和异常处理

    2021-07-28 05:46:15
  • 选择一个优秀正文字体的15个技巧

    2008-03-20 13:36:00
  • 解决PyCharm同目录下导入模块会报错的问题

    2023-06-12 22:39:55
  • HTML5本地存储初探(三)

    2010-03-07 15:49:00
  • python中的zip模块

    2023-09-13 07:49:56
  • 怎么快速自学python

    2023-06-25 19:19:32
  • 驯服不听话的网页表格

    2007-12-03 11:36:00
  • AJAX打造博客无刷新搜索

    2007-08-23 08:48:00
  • asp之家 网络编程 m.aspxhome.com