正则表达式初体验

96
波罗学的草稿
2019.03.06 23:26* 字数 1811
image

简书不维护了,欢迎关注我的知乎:波罗学的个人主页

在程序员的日常工作中,文本查找匹配是很常见的。其可通过简单字符比较、通配符规则和正则表达式等方式实现。其中正则表达式是最强大的文本匹配查找工具。

什么是正则表达式

正则表达式英文RegularExpression,最早起源于对人类神经网络的研究,后来这一研究被人们应用到了计算搜索算法中。

那么具体啥是正则表达式呢?

正则表达式是由一系列普通与特殊字符组成的用于描述文本规则的表达式,简言之可理解为是描述一段文本组成规则的语言。比如,文本以#开头,包含有4位数字和包含polo单词等规则。

正则表达式的用处很多,下面列举一些常见场景

  • 输入框表单验证,如昵称、邮箱、手机号码验证等
  • HTML文本解析,如网页爬虫获取a标签的href属性
  • 代码搜索,IDE基本都支持正则查找
  • 操作系统中文件匹配搜索替换分析,如Linux文本处理三剑客grep、sed和awk对正则都支持。

总的来说,正则表达式使用场景多样,各种系统各种语言都有支持,已经是现代计算机科学中必不可少的强大工具。

测试工具

为减少各位朋友因平台差异导致的测试不便,这里采用网页测试工具说明。下面介绍两款工具

  • 一个为正则解析工具,以图形语言解释正则,不支持文本匹配测试
  • 一个为正则验证工具,功能强大,支持文本测试功能

具体介绍如下

工具一 解析工具

以友好的图形语言来解释正则,工具地址https://regexper.com,如下所示

image

开始输入测试正则^h{3}-\d+-\w*$,图形解析结果,首先行开始(Start of line),“h”出现3次(本身加上2次循环),紧随其后为1次“-”,之后为digit(数字)1至多次,紧随其后一次“-”,之后以任意次word(字符)结束。个人觉得比较形象易于理解,本质是在用另一种易于理解的图形语言描述正则。

虽然解析工具对正则进行了图形解析,但没经过文本测试还是不够放心。我们需要一款验证正则的工具,支持文本测试。

工具二 验证工具

下面介绍这款新工具,地址https://regex101.com,支持文本测试,且有详细的文字说明。在解析工具解析正则没有问题后,下面使用此工具进行文本验证。测试文本如下

hhh-221-jjj

验证结果如下

image

此处显示“hhh-221-jjj”选中着色,即为匹配成功,基本可以确定正则无误。
是不是觉得这个工具很方便,其实它还有很多功能,下面就此工具简单介绍一下

  • 正则表达式(REGULAR EXPRESSION) 正则编辑框,示例中尾部g表示全局模式,支持多种模式,如忽略大小写、多行模式,unicode模式等
  • 测试文本(TEST STRING) 测试文本输入框,会对匹配文本着色,此处hhh-221-jjj被选中着色
  • 正则说明(EXPLANATION) 说明正则含义,可理解为图形解析工具的文字版
  • 匹配信息(MATCH INFORMATION) 上图右中,示例匹配文本位置0-11,内容“hhh-221-jjj”
  • 速查手册(QUICK REFERENCE) 上图右下框,可快速查看正则使用方法
  • 其他 支持多种语言正则,代码自动生成,提供正则调试器,还可以将正则保存等,具体详情可自行了解

上面两个网页工具,大家或许更喜欢第二个工具,毕竟是所见即所得。

实例体验

这里介绍两个例子,初步了解下正则表达式能处理什么场景,究竟有多牛逼。

搜索指定单词

首先演示文本如下

My name is poloxue. I haven't a polo car and polo t-shirt

从上述文本中搜索出polo这个单词,直接使用polo进行搜索的话,验证工具结果如下

image

上图除了将polo搜索出来以外,还将poloxue搜索了出来,正如我们常用搜索的效果,这并不能满足我们的需求。

为了达到这个目标,这里引入特殊符号\b,正则表达式中的元字符,其含义为单词的分界符。验证工具结果如下

image

好,这里只选中了我们搜索的单词polo,而poloxue不是polo单词,实现了我们的目标。

下面看看解析工具的图形解析

image

解析结果为,文本规则是word boundary(单词边界)加上“polo”加上(单词边界)。这就是元字符\b的含义了。

搜索手机号码

示例目标是从一段复杂的文本中,搜索所有的手机号码

在开始解题前,先了解下手机号码的规则

号码位数:11位
13+9位任意数字
15[012356789]+8位任意数字
18[0256789]+8位任意数字
170[059]+7位任意数字

满足如下所有条件的正则表达式 \b(13\d{9}|15[0-35-9]\d{8}|18[025-9]\d{8}|170[059]\d{7})\b

这里使用\b单词边界是为了防止类似153122108880123456也匹配成功。和上个示例的搜索指定单词情况类似。

使用解析工具图解此正则,结果如下

image

下面使用验证工具验证一下,假设有如下一段文本

A: What is your ID number?B: My ID number is 321323200210230023A: What is your mobile number?B: My mobile number is 15312210888

验证工具测试结果如下

image

此示例用到了正则中很多特性,如

重复元字符{}指定某类字符重复重现的次数,如\d{9}表示连续9个数字
范围元字符[]指定字符范围,如[0-35-9]表示为0-3和5-9间九数任一字符
分支元字符”|“实现,可理解为正则的“或”,文本匹配”|“分隔的任一正则即可。
分组元字符()里的正则相当于子正则,在示例中使用”()“分组防止\b作用于整体而不是分支中的某一正则

当然,元字符的特性远不止于此,更多的特性如后向引用、反义、零宽断言等等提供了更多强大功能。

此篇文章还算短小精悍,没有涉及正则太多知识。对于不了解正则的朋友阅读会有困难。

爬虫技术