中文自然语言处理系列之一:正则匹配


本文汇总了部分中文自然语言处理中常用的,比较复杂的正则表达式,但并不是都是原创,部分引用了现有的网络资源,特此声明。


       相对其他语言的自然语言处理的领域,中文自然语言处理有其独特之处。即使是中文文本的处理,就有很多特有的处理细节。在中文文本处理时,经常需要用到许多正则表达式,而部分正则表达式的设计需要丰富的中文文本处理经验,才能在处理不同来源的文本时保持良好的性能。笔者收集了一些中文文本处理时常用的正则表达式,这些正则表达式都是经过精心设计的,性能也经过长期的测试验证,有着良好的实用效果。

1. 邮箱地址

       邮箱地址一般可分为三个部分,用户名,@符号,以及邮箱服务的域名,形如:username@example.com,其中用户名的字符限制在大小写字母(a-zA-Z),数字(0-9),下划线(_),横线(-)以及英文句号(.),并开头必须是字母,而域名则至少有顶级域名及一级域名。因此邮箱地址的正则表达式需要考虑其组成结构以及用户名和域名的组成,其正则表达式如下:

([\w\d_\.\-]+)@([\w\d\-]+)(\.[\w\d\-]+)*(\.[\w\d]{2,6})

       邮箱地址的正则表达式的结构分解如下图所示:

图1 邮箱地址的正则表达式的结构

2. 手机号码

       对于国内手机号码的正则表达式,Github的项目ChinaMobilePhoneNumberRegex针对不同的需求,设计了对应的正则表达式,本文选取了该项目提供的匹配所有手机号码的正则表达式。而关于国内手机号码的详细说明可以参考维基百科的文章,此处只作简要的介绍。

       手机号码一般由十一位数字组成,有时还会加上国际区号,具体的组成如下表所示:

位数 含义 说明
- 国际区号 +86
1~3位 网络识别号 手机运营商,每个运营商分配有不同的字段,都以1开头
4~7位 地区编码 识别手机归属地
8~11位 用户号码 随机分配

网络识别号均是由特别的数字编号组成的,目前只有有限的数字编号,但不时会新增,具体可以参考维基百科的文章

       考虑国际区号,手机号码的正则表达式如下所示:

(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[35678]\d{2}|4(?:0\d|1[0-2]|9\d))|9[189]\d{2}|66\d{2})\d{6}

       同样给出手机号码的正则表达式的结构解析:

图2 手机号码的正则表达式的结构

3. URL

       URL相对比较复杂,要设计比较通用的URL匹配正则表达式确实是比较困难的事。无意中发现的一篇博文专门对URL的匹配正则表达式的设计进行了研究,分别给出了通用的URL匹配正则表达式和网站URL的匹配正则表达式,其中通用的URL正则表达式如下所示:

((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))

       博文同样给出了URL的匹配正则表达式的组成结构,具体说明如下:

(                                             # 开始匹配整个URL
    (?:
        [a-z][\w-]+:                          # URL的协议及冒号
            (?:
                /{1,3}                        # 1-3斜杠
                |                             # 或者
                [a-z0-9%]                     # 单个字母,数字或者百分号
             )
        |                                     # 或者
        www\d{0,3}[.]                         # 万维网符号,如"www.","www1.", "www2." 等
        |                                     # 或者
        [a-z0-9.\-]+[.][a-z]{2,4}/            # 类似于域名加上斜杠
    )
    (?:                                       # 一个或多个组
        [^\s()<>]+                            # 没有空格以及-,(,),<,>中的任意一个字符
        |                                     # 或者
        \(([^\s()<>]+|(\([^\s()<>]+\)))*\)    # 两级括号对
     )+
     (?:                                      # URL结尾
         \(([^\s()<>]+|(\([^\s()<>]+\)))*\)   # 两级括号对
        |                                     #   或者
        [^\s`!()\[\]{};:'".,<>?«»“”‘’]        # 无空格及英文标点
     )
)

       上述URL的正则表达式可用于URL的匹配,但如果需要对URL进行解析,可参考Github上的项目js-url

4. 身份证号

       常见的身份证号码为十八位,但早期的身份证号码是十五位数,后来考虑到千年虫的问题,有添加了18位身份证的号码编制规则。其中十八位的身份证的组成如下表所示:

含义 位数 约束
省、自治区、直辖市代码 1~2位 起始数字不为0
地级市、盟、自治州代码 3~4位 -
县、县级市、区代码 5~6位 -
出生年月日 7~14位 日期格式
顺序号 15~17位 17位奇数为男,偶数为女
校验码 18位 数字或者字母X

十五身份号码与十八位身份证号码的区别有两处,其一是十五位身份证号码的年的编码只有两位,其二是没有最后的校验码,就比十八位的身份证少了三位数字。

       十八位身份证号码的匹配正则表达式如下:

[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]

其结构分解如下图所示:

图3 十八位身份证号码的正则表达式的结构

       十五位身份证号码的匹配正则表达式如下:

[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}

其结构分解如下:

图4 十五位身份证的正则表达式的结构

将两个正则表达式结合在一起,便可得到最终完整的身份证的匹配正则表达式了。

       最后推荐几个调试正则表达式的网站:Regular Expressions 101RegExrDebuggex

持续更新中

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,104评论 0 9
  • 忘了从哪收集的资料了,放这儿,以备不时之需。 只能输入数字:"^[0-9]*$"。 只能输入n位的数字:"^\d{...
    study_monkey阅读 1,362评论 0 7
  • 在每个死胡同的尽头,都有另一个维度的天空。 | 廖一梅 | 你像一片阳光,融化了我内心执拗的整座冰山。 1. 开头...
    _婧雯阅读 805评论 1 3
  • 我要写一万首诗给你 只希望你冲我一笑,并知道 我曾经一万天的飘摇 只为这一天能抓住夕阳的衣角 带我重回梦中的地方 ...
    泰安左眼皮跳跳阅读 122评论 0 7