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抓取最新博客内容并生成Rss
May 17 Python
Python上下文管理器和with块详解
Sep 09 Python
Python利用正则表达式实现计算器算法思路解析
Apr 25 Python
Python中的支持向量机SVM的使用(附实例代码)
Jun 26 Python
详解如何减少python内存的消耗
Aug 09 Python
python-tornado的接口用swagger进行包装的实例
Aug 29 Python
Python 私有化操作实例分析
Nov 21 Python
matplotlib绘制多个子图(subplot)的方法
Dec 03 Python
基于python3的socket聊天编程
Feb 17 Python
Python小白学习爬虫常用请求报头
Jun 03 Python
keras 获取某层的输入/输出 tensor 尺寸操作
Jun 10 Python
python自动化测试三部曲之unittest框架的实现
Oct 07 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中计算程序运行时间的类代码
2012/11/03 PHP
PHP设计模式之责任链模式的深入解析
2013/06/13 PHP
PHP 8新特性简介
2020/08/18 PHP
PHP filter_var() 函数, 验证判断EMAIL,URL等
2021/03/09 PHP
ToolTips JQEURY插件之简洁小提示框效果
2011/11/19 Javascript
关于JS管理作用域的问题
2013/04/10 Javascript
js replace 与replaceall实例用法详解
2013/08/03 Javascript
查找iframe里元素的方法可传参
2013/09/11 Javascript
js电话号码验证方法
2015/09/28 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
hammer.js实现图片手势放大效果
2017/08/29 Javascript
vue 项目build错误异常的解决方法
2019/04/22 Javascript
vue2之简易的pc端短信验证码的问题及处理方法
2019/06/03 Javascript
layui 上传文件_批量导入数据UI的方法
2019/09/23 Javascript
js仿360开机效果
2019/12/26 Javascript
Vue $emit()不能触发父组件方法的原因及解决
2020/07/28 Javascript
[15:35]教你分分钟做大人:天怒法师
2014/10/30 DOTA
[04:50]DOTA2亚洲邀请赛小组赛第四日 TOP10精彩集锦
2015/02/02 DOTA
Python访问MySQL封装的常用类实例
2014/11/11 Python
selenium+python实现自动登录脚本
2018/04/22 Python
利用python脚本如何简化jar操作命令
2019/02/24 Python
django formset实现数据表的批量操作的示例代码
2019/12/06 Python
Windows下实现将Pascal VOC转化为TFRecords
2020/02/17 Python
python 追踪except信息方式
2020/04/25 Python
Python如何执行精确的浮点数运算
2020/07/31 Python
Python实现自动装机功能案例分析
2020/10/22 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
如何给HTML标签中的文本设置修饰线
2019/11/18 HTML / CSS
中国电视购物:快乐购
2017/02/04 全球购物
汽车制造与装配专业自荐信范文
2014/01/02 职场文书
小学生感恩父母演讲稿
2014/08/28 职场文书
订货会邀请函
2015/01/31 职场文书
2015年第31个教师节致辞
2015/07/31 职场文书
2016年第29个世界无烟日宣传活动总结
2016/04/06 职场文书
MySQL 表空间碎片的概念及相关问题解决
2021/05/07 MySQL
前端实现滑动按钮AJAX与后端交互的示例代码
2022/02/24 Javascript