本文由来
在做抽取日常短语中地名(包括省市区县街道社区道路)的工作,待处理的文本都是常用语,本身该工作也只是一个小工程,暂时没有花时间学术研究模型,也不太在意准确率。语言是python,有一些bug和处理方法建议,主要是关于中文句子的正则匹配,记录下来以备不时之需。
汉字正则和取字符问题
问题:需要匹配该句子的规则性很强的部分汉字。例如:我去了长安路买东西。识别路的结果应为“长安路”
str=u'我去长安路买东西' pattern = re.compile(ur'[去,走,了]{1,2}([\u4e00-\u9fa5]{2,3}路)') target = re.findall(pattern, str) for item in target: print item
注:
[\u4e00-\u9fa5]
是中文字符的字符集。{2,3}
表名该字符集可以重复两到三次,也就是说,介词和路之间限制了只能有两到三个汉子,此情况下,我们认为这是一个路名(极可能是路名,但也可能不是)str
必须是unicode编码,即u'我是待匹配字符串'
,此时才输出匹配结果。如果读取的是utf-8的文本,正则匹配前读取到的行内容一定要先解码line.decode(utf-8)
- 特别地,句子可能是“走了”、“去了”,针对这种情况,我们加入重复花括号
{}
,这样不必在字符集中穷举所有两字词语,只需要穷举可能出现的字,允许1到2次重复就可以了。
抽取汉字:待读取文本本身是utf-8编码,通过python程序读入后,应先解码后编码,才能保证在不乱码的情况下提取对应某个具体的字。python程序读入代码:
file = open('f:/test.txt', 'r') for (num, line) in enumerate(file): print "LineNum"+str(num)+" : "+line #行号从0开始 print line[2] #出现乱码 newstr1=line.decode('utf-8')[0:3].encode('utf-8') newstr2=line.decode('utf-8')[2].encode('utf-8') print newstr1 #输出“周末” print newstr2 #输出“末” print newstr2=='末' #输出 true
注:
[1:3]
代表包括第一个汉字起,到第三个汉字结束,但不包括第三个汉字。如果想全部输出,则写为[0:-1]。
- 先把utf-8字符串解码为unicode才能输出对应位(汉字位从1开始)。2.x版本中,字符串有str和unicode两种类型,str有各种编码区别,例如utf-8、utf-16、gbk等等,unicode是没有编码的标准形式。unicode通过编码(encode函数指定编码类型)转化成str,str通过解码(decode函数)转化成unicode。在进行同时包含 str 类型和 unicode 类型的字符串操作时,Python2 一律都把 str 解码(decode)成 unicode 再运算。
- 字符串单引号和双引号问题:在表示字符串时,是没有区别的。
但是如果你的字符串中本身有单引号,那整个字串用双引号就省得将原字串中的单引号转义。如果字串中本身有双引号,那就用单引号扩起整个字串,也是省去转义。
文本读写
读取txt中某一行内容:
# 读取文本中某行内容(文本序号从1开始) count = linecache.getline('f:/userdict.txt', num)
读取行号和行内容:
#文本序号从0开始 file = open('f:/test.txt', 'r') for (num, line) in enumerate(file): print num,line
循环输出列表内容(包括索引)
def printList(list): for index,item in enumerate(list): print index,"|", item
注意索引是从1开始的
对比当前字符串和词典文本中字符串是否相同的函数(主要参考带注释部分的代码)
def findDirString(str,dict): file = open('f:/userdict.txt', 'r') flag=0 for (num, value) in enumerate(file): # 输出行号和行内容 (序号从0开始) # print "line number", num, "is:", value line=value.decode('utf-8')[0:-1].strip();# 对文本解码并去掉字符串前后的空格 if str.__eq__(line): if line[-1] not in [u'省',u'市',u'区',u'县']: count = linecache.getline('f:/userdict.txt', num)# 读取文本中某行内容(序号从1开始) cla = count.decode('utf-8')[0:-1].strip()[-1] flag=1 dict[str]=cla return 1 return 0