Python检测生僻字的实现方法


Posted in Python onOctober 23, 2016

解决思路

首先想到的就是利用 python 的正则表达式来匹配非法字符,然后找出非法记录。然而理想总是丰满的,现实却是残酷的。在实现的过程中,才发现自己对于字符编码、以及 python 内部字符串表示的相关知识的缺乏。在这期间,踩过了不少坑,到最后虽然还有些模糊的地方,但总算有一个总体清晰的了解。在此记录下心得,避免以后在同一个地方跌倒。

以下的测试环境是 ArcGIS 10.3 自带的 python 2.7.8 环境,不保证其他 python 环境也适用。

python 正则表达式

python 中的正则功能由内嵌的 re 函数库提供,主要用到 3 个函数。re.compile() 提供可重用的正则表达式,match() search() 函数返回匹配结果,两者之间的区别在于: match() 从指定位置开始匹配,search() 会从指定位置向后搜索直到找到匹配字符串。例如下面的代码中,match_result 从第一个字符 f 开始匹配,匹配失败返回空值;search_result 从 f 开始向后搜索,直到找到第一个匹配的字符 a, 然后通过 group() 函数输出匹配结果为字符 a。

import re

pattern = re.compile('[abc]')
match_result = pattern.match('fabc')
if match_result:
 print match_result.group()

search_result = pattern.search('fabc')
if search_result:
 print search_result.group()

以上的实现方式需要先编译一个 pattern,然后再进行匹配。实际上,我们可以直接利用 re.match(pattern, string) 函数来实现相同的功能。但是直接匹配的方式没有先编译再匹配的方式灵活,首先是正则表达式没办法重用,如果大量数据进行同一模式匹配,意味着每次都需要内部编译,造成性能损失;另外,re.match() 函数没有 pattern.match() 功能强大,后者可以指定从哪个位置开始匹配。

编码问题

了解 python 正则的基本功能后,剩下的事情就是找到一个合适的正则表达式来匹配生僻字和非法字符。非法字符很简单,采用以下 pattern 就可以实现匹配:

pattern = re.compile(r'[~!@#$%^&* ]')

然而对于生僻字的匹配,着实难倒了我。首先是对于生僻字的定义,什么样的字算生僻字?经过咨询项目经理,规定非 GB2312 的字符属于生僻字。接下来的问题是,如何匹配 GB2312 字符?

经过查询,GB2312 的范围是 [\xA1-\xF7][\xA1-\xFE] ,其中汉字区的范围是 [\xB0-\xF7][\xA1-\xFE] 。因此,添加生僻字匹配后的表达式为:

pattern = re.compile(r'[~!@#$%^&* ]|[^\xA1-\xF7][^\xA1-\xFE]')

问题似乎是顺理得当地解决了,然而我还是 too simple too naive 。由于要判断的字符串都是从图层文件读取的,arcpy 贴心地将读取的字符编码为 unicode 格式。因此,我需要找出 GB2312 字符集在 unicode 中的编码范围。但现实是,GB2312 字符集在 unicode 中的分布并不是连续的,使用正则表示这个范围必定是非常复杂的。使用正则表达式匹配生僻字的构想,似乎陷入了死胡同。

解决方案

既然提供的字符串是 unicode 格式,那么我可不可以将其转换为 GB2312 再进行匹配呢?实际上是不行,因为 unicode 字符集要远大于 GB2312 字符集,因此 GB2312 => unicode 总是可以实现的,而反过来 unicode => GB2312 不一定能成功。

这突然为我提供了另外一种思路,假设一个字符串的 unicode => GB2312 转换会失败,那么是不是恰恰说明了它不属于 GB2312 字符集?所以,我使用 unicode_string.encode('GB2312') 函数尝试转换字符串,捕获 UnicodeEncodeError 异常来识别生僻字。

最终的代码如下:

import re

def is_rare_name(string):
 pattern = re.compile(u"[~!@#$%^&* ]")
 match = pattern.search(string)
 if match:
 return True

 try:
    string.encode("gb2312")
  except UnicodeEncodeError:
   return True

  return False

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Python 相关文章推荐
Python中实现参数类型检查的简单方法
Apr 21 Python
简介Python中用于处理字符串的center()方法
May 18 Python
Python2随机数列生成器简单实例
Sep 04 Python
python中使用正则表达式的连接符示例代码
Oct 10 Python
Python 中的lambda函数介绍
Oct 10 Python
启动Atom并运行python文件的步骤
Nov 09 Python
对DataFrame数据中的重复行,利用groupby累加合并的方法详解
Jan 30 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
Feb 18 Python
opencv中图像叠加/图像融合/按位操作的实现
Apr 01 Python
python框架flask入门之环境搭建及开启调试
Jun 07 Python
python3.8动态人脸识别的实现示例
Sep 21 Python
python爬虫构建代理ip池抓取数据库的示例代码
Sep 22 Python
python 写入csv乱码问题解决方法
Oct 23 #Python
解决Python中字符串和数字拼接报错的方法
Oct 23 #Python
python 读写txt文件 json文件的实现方法
Oct 22 #Python
Python类属性的延迟计算
Oct 22 #Python
如何在Python函数执行前后增加额外的行为
Oct 20 #Python
如何利用Fabric自动化你的任务
Oct 20 #Python
windows下ipython的安装与使用详解
Oct 20 #Python
You might like
PHP Session变量不能传送到下一页的解决方法
2009/11/27 PHP
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
2012/09/07 PHP
Extjs4实现两个GridPanel之间数据拖拽功能具体方法
2013/11/21 Javascript
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
2014/01/09 Javascript
JS代码防止SQL注入的方法(超简单)
2016/04/12 Javascript
Javascript中获取浏览器类型和操作系统版本等客户端信息常用代码
2016/06/28 Javascript
详细谈谈AngularJS的子级作用域问题
2016/09/05 Javascript
JS正则表达式学习之贪婪和非贪婪模式实例总结
2016/12/26 Javascript
详解JS判断页面是在手机端还是在PC端打开的方法
2019/04/26 Javascript
使用kbone解决Vue项目同时支持小程序问题
2019/11/08 Javascript
JS函数本身的作用域实例分析
2020/03/16 Javascript
在Python中操作字典之setdefault()方法的使用
2015/05/21 Python
CentOS下使用yum安装python-pip失败的完美解决方法
2017/08/16 Python
python 监听salt job状态,并任务数据推送到redis中的方法
2019/01/14 Python
python-itchat 统计微信群、好友数量,及原始消息数据的实例
2019/02/21 Python
使用Django开发简单接口实现文章增删改查
2019/05/09 Python
python实现两个dict合并与计算操作示例
2019/07/01 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
python小项目之五子棋游戏
2019/12/26 Python
Python属性和内建属性实例解析
2020/01/14 Python
Python实现遗传算法(二进制编码)求函数最优值方式
2020/02/11 Python
奥地利顶级内衣丝袜品牌英国站:Wolford英国
2016/08/29 全球购物
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
电大学习个人自我评价范文
2013/10/04 职场文书
信息管理应届生求职信
2014/03/07 职场文书
拒绝黄毒毒宣传标语
2014/06/26 职场文书
机械工程及其自动化专业求职信
2014/08/08 职场文书
高中生学习计划书
2014/09/15 职场文书
班级光棍节联谊会策划书
2014/10/10 职场文书
紧急通知
2015/04/17 职场文书
党小组评议意见
2015/06/02 职场文书
python基础之while循环语句的使用
2021/04/20 Python
Go语言空白表示符_的实例用法
2021/07/04 Golang
mybatis 获取无数据的字段不显示的问题
2021/07/15 Java/Android
golang中的struct操作
2021/11/11 Golang
浅谈MySql整型索引和字符串索引失效或隐式转换问题
2021/11/20 MySQL