python 文本处理 保留中英文和标点符号_【NLP】Python NLTK处理原始文本

作者:白宁超

2016年11月8日22:45:44

摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的一种自然语言工具包,其收集的大量公开数据集、模型上提供了全面、易用的接口,涵盖了分词、词性标注(Part-Of-Speech tag, POS-tag)、命名实体识别(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各项 NLP 领域的功能。本文主要介绍:1)怎样编写程序访问本地和网络上的文件,从而获得无限的语言材料?2)如何把文档分割成单独的单词和标点符号,并进行文本语料上的分析?3)怎样编写程序产生格式化输出,并把结果保存在文件中?关于Python基础知识可以参看本人的【Python五篇慢慢弹】系列文章(本文原创编著,转载注明出处:Python NLTK处理原始文本)

目录

关于处理原始文本部分导入语句:

>>> from __future__ import division

>>> import nltk,re,pprint

1 从网络和硬盘访问文本(在线获取伤寒杂病论)

python网络访问程序:

>>> from __future__ import division

>>> import nltk,re,pprint

>>> from urllib.request import urlopen

>>> url=r'http://www.gutenberg.org/files/24272/24272-0.txt'

>>> raw=urlopen(url).read()

>>> raw = raw.decode('utf-8')

>>> len(raw)

70306

>>> raw[2000:2500]

运行结果:

对其中文分词:

>>> from nltk.tokenize import StanfordSegmenter

>>> segmenter = StanfordSegmenter(

path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-segmenter.jar",

path_to_slf4j=r"E:\tools\stanfordNLTK\jar\slf4j-api.jar",

path_to_sihan_corpora_dict=r"E:\tools\stanfordNLTK\jar\data/",

path_to_model=r"E:\tools\stanfordNLTK\jar\data\pku.gz",

path_to_dict=r"E:\tools\stanfordNLTK\jar\data\dict-chris6.ser.gz"

)

>>> result = segmenter.segment(raw)

>>> result[1000:2500]

分词结果:

2 在线获取处理HTML文本(红楼梦)

在线获取html文本资料:

>>> import re,nltk

>>> from urllib.request import urlopen

>>> url='http://www.gutenberg.org/cache/epub/24264/pg24264-images.html'

>>> html=urlopen(url).read()

>>> html=html.decode('utf-8')

>>> html[5000:5500]

运行结果:

相关正则知识:

\d  匹配一个数字

\w 匹配一个字母或者数字

*  任意个字符(包括0个),

+  至少一个字符

?  0个或1个字符

{n} n个字符

{n,m} n-m个字符

\s 匹配一个空格

\s+ 至少有一个空格

\d{3,8} 表示3-8个数字,例如'1234567'

\d{3}\s+\d{3,8}

[0-9a-zA-Z\_] 匹配一个数字、字母或者下划线

[0-9a-zA-Z\_]+ 匹配至少由一个数字、字母或者下划线组成的字符串,

比如'a100','0_Z','Py3000'等等;

[a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量

[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)

A|B可以匹配A或B,所以(P|p)ython可以匹配'Python'或者'python'

^表示行的开头,^\d表示必须以数字开头

$表示行的结束,\d$表示必须以数字结束

正则表达式进行数据清洗:

>>> len(html)

962651

>>> strhtml=re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。??、~@#¥%……&*()]+|[A-Za-z0-9]+","",html)#去掉中英文符号

>>> len(strhtml)

781150

>>> strhtml[5000:5500]

清洗后结果:

红楼梦进行中文分词

>>> # 红楼梦进行中文分词

>>> from nltk.tokenize import StanfordSegmenter

>>> segmenter = StanfordSegmenter(

path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-segmenter.jar",

path_to_slf4j=r"E:\tools\stanfordNLTK\jar\slf4j-api.jar",

path_to_sihan_corpora_dict=r"E:\tools\stanfordNLTK\jar\data/",

path_to_model=r"E:\tools\stanfordNLTK\jar\data\pku.gz",

path_to_dict=r"E:\tools\stanfordNLTK\jar\data\dict-chris6.ser.gz"

)

>>> result = segmenter.segment(raw)

查找分析:查找“曰”后面的内容

re.findall(r'(曰.{,3})',strhtml)

备注:处理搜索引擎的结果:基于自己配置的搜索引擎处理

3 处理RSS订阅

>>> import feedparser #feedparser需要在python库中下载

>>> llog=feedparser.parse(url)

4 读取本地文件:strip()方法删除输入行结尾的换行符

方法一:

>>> f=open(r"E:\dict\q0.txt","r")

>>> for line in f:

print(line.strip())

方法二:

>>> with open(r"C:\Users\cuitbnc\Desktop\dqdg.txt","r+") as f:

str=f.read()

方法三:

>>> import nltk

>>> path=nltk.data.find(r'C:\Users\cuitbnc\Desktop\dqdg.txt')

>>> raw=open(path,'rU').read()

>>> len(raw)

673167

>>>

PDF或者MSWord以及其他二进制提取文本,利用第三方函数库pypdf和pywin32

>>> raw=open(r"E:\dict\q0.txt","r").read()

>>> tokens=nltk.word_tokenize(raw)

>>> words=[w for w in tokens]

>>> vocab=sorted(set(words))

>>> vocab

5 字符串:最底层的文本处理

有用的字符串方法:

s.find(t)  字符串s中包含t的第一个索引s.rfind(t)  字符串s中包含t的最后一个索引

s.index(t)  与s.find(t)类似

s.rindex(t)  与s.rfind(t)类似

s.join(text)

s.split(t)  字符串分割

s.splitlines()

s.lower()

s.upper()

s.titlecase() s首字母大写

s.strip()  返回一个没有首尾空白字符的s的复制

s.replace(t,u) 用u替换s中的t

链表和字符串的差异:字符串和链表都是一种序列,可以通过索引抽取他们一部分,可以切片,可以合并。但是,链表和字符串不能连接

6 使用Unicode进行文字处理

解码:文件中的文本都有特定的编码,需要一些机制将文本翻译成Unicode的过程就是解码。 编码:将Uniocde写入一个文件或者终端,首先需要将Unicode转化为合适的编码,这个过程就是编码

中文解码问题

>>> raw=open(r"E:\dict\text.txt","r").read()

Traceback (most recent call last):

File "", line 1, in

raw=open(r"E:\dict\text.txt","r").read()

UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 16: illegal multibyte sequence

>>> import codecs

>>> f=codecs.open(r"E:\dict\text.txt",'r',encoding="utf-8").read()

ord()查找字符的整数序列

>>> ord('a')

97

>>> ord('f')

102

7 使用正则表达式检测词组搭配

import re 导入re函数库

re.search('ed$',w)查询w字符串中是都ed结尾匹配 [w for w in wordlist if re,search('ed$',w)]

通配符“.”可以用来匹配任何单个字符。例如:有一个8个字母组成的字谜,j是第三个字母,t的第六个字母,每个空白单元格用句点隔开.(^字符串开始,$字符串结束)

[w for w in wordlist if re.search('^..j..t..$',w)]

计算文本中词出现次数 sum(w for w in text if re.search('^e-?mail$',w))

搜索数字

[w for w in wordlist if re.search('^[0-9]+\.[0-9]+$',w)]

[w for w in wordlist if re.search('^[0-9]{4}$',w)]

python正则表达式基本元字符

.   通配符,匹配所有字符

^abc  匹配以abc开始的字符串

abc$  匹配以abc结尾的字符串

[abc]  匹配字符集合

[A-Z0-9] 匹配字符范围

ed|ing|s 匹配指定的字符串,诸如ed或者ing或者s

*   前面项目0个或者多个,如a*/[a-z]* (也叫Kleene闭包)

+   前面项目1个或者多个,如a+、[a-z]+

?   前面项目0个或者1个,如a?、[a-z]?

{n}   重复n次

{n,}  至少重复n次

{,n}  重复不多于n次

{m,n}  至少重复m次不多于n次

a(b|c)+  括号表示操作符的范围

正则表达式符号:

\b 词边界

\d 任何数字等于[0-9]

\D 任何非数字等于[^0-9]

\s 任何空白字符[\t\n\r\f\v]

\S 任何非空白字符[^\t\n\r\f\v]

\w 任何字母[A-Za-z0-9]

\W 任何非字母[^A-Za-z0-9]

\t 制表符

\n 换行符

指定条件查询分析:

>>> f=codecs.open(r"E:\dict\q0.txt",'r').read()

>>> import re

>>> re.findall(r"大秦",f)

['大秦']

>>> re.findall(r"庞涓",f)

['庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓', '庞涓']

>>> len(re.findall(r"庞涓",f))

33

>>>

【推荐】

你可能感兴趣的:(python,文本处理,保留中英文和标点符号)