文档章节

初探正则表达式

Rksi5
 Rksi5
发布于 2014/06/23 23:31
字数 3387
阅读 133
收藏 23
点赞 0
评论 0

    在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。
    
    假设你在一篇英文小说里查找hi,你可以使用正则表达式hi。这几乎是最简单的正则表达式了,它可以精确匹配这样的字符串:由两个字符组成,前一个字符是h,后一个是i。然而,
    很多单词里包含hi这两个连续的字符,比如him,history,high等等。用hi来查找的话,这里边的hi也会被找出来。如果要精确地查找hi这个单词的话,我们应该使用\bhi\b。
    \b是正则表达式规定的一个特殊代码(元字符),代表着单词的开头或结尾。
    
    1、元字符
    ---------------------------------------------------
        代码            说明
        .                匹配除换行符以外的任意字符
        \w                匹配字母或数字或下划线或汉字
        \s                匹配任意的空白符
        \d                匹配数字
        \b                匹配单词的开始或结束
        ^                匹配字符串的开始
        $                匹配字符串的结束
    ---------------------------------------------------
        ^\d{5,8}$ : 匹配5位到12位数字。
                    {5,12}则是重复的次数不能少于5次,不能多于12次,否则都不匹配。因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字。
    
    2、字符转义
        如果你想查找元字符本身的话,如(.或*)就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\。
        例如:deerchao\.net匹配deerchao.net。
    
    3、限定字符
    ---------------------------------------------------
        代码            说明
        *                重复零次或更多次
        +                重复一次或更多次
        ?                重复零次或一次
        {n}                重复n次
        {n,}            重复n次或更多次
        {n,m}            重复n到m次
    ---------------------------------------------------    
        如:Windows\d+ 匹配Windows后面跟1个或更多数字。
        
    4、字符类
        要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?
        很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。
        如:[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。
            \(?0\d{2}[) -]?\d{8}
                这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455,或02912345678等。
                首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。
    
    5、分枝条件
        上面的\(?0\d{2}[) -]?\d{8},也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。
        正则表达式里的分枝条件指的是有几种规则,如果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。
        如:
            0\d{2}-\d{8}|0\d{3}-\d{7} 匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
            \(?0\d{2}\)?[- ]?\d{8}|0\d{2}[- ]?\d{8} 匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间隔,也可以没有间隔。
            \d{5}-\d{4}|\d{5} 用于匹配美国的邮政编码。美国邮编的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。
                            如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮编的前5位)。
                            原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
                            
    6、分组
        我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。
        (\d{1,3}\.){3}\d{1,3} 是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重复3次,
                            最后再加上一个一到三位的数字(\d{1,3})。
                            然而,它也将匹配256.300.888.999这种不可能存在的IP地址,如果能使用算术比较的话,或许能简单地解决这个问题,但是正则表达式中并不提供关于数学的任何功能,所以只能使用冗长的分组。
                            选择,字符类来描述一个正确的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
                
    7、反义
        有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义。
        ---------------------------------------------------
        代码            说明
        \W                匹配任意不是字母,数字,下划线,汉字的字符
        \S                匹配任意不是空白符的字符
        \D                匹配任意非数字的字符
        \B                匹配不是单词开头或结束的位置
        [^x]            匹配除了x以外的任意字符
        [^aeiou]        匹配除了aeiou这几个字母以外的任意字符
        ---------------------------------------------------    
        如:\S+匹配不包含空白符的字符串;<a[^>]+>匹配用尖括号括起来的以a开头的字符串
        
    8、后向引用
        使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。
        默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
        后向引用用于重复搜索前面某个分组匹配的文本。例如,\1代表分组1匹配的文本。
        如:\b(\w+)\b\s+\1\b 可以用来匹配重复的单词,像go go, 或者kitty kitty。
            首先是一个单词,也就是单词开始处和结束处之间的多于一个的字母或数字(\b(\w+)\b),这个单词会被捕获到编号为1的分组中,然后是1个或几个空白符(\s+),最后是分组1中捕获的内容(也就是前面匹配的那个单词)(\1)。
        你也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:
            (?<Word>\w+)(或者把尖括号换成'也行:(?'Word'\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。
        ---------------------------------------------------
        分类            代码            说明
        捕获            (exp)            匹配exp,并捕获文本到自动命名的组里
        捕获            (?<name>exp)     匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp)
        捕获            (?:exp)            匹配exp,不捕获匹配的文本,也不给此分组分配组号
        零宽断言        (?=exp)            匹配exp前面的位置
        零宽断言        (?<=exp)        匹配exp后面的位置
        零宽断言        (?!exp)            匹配后面跟的不是exp的位置
        零宽断言        (?<!exp)        匹配前面不是exp的位置
        注释            (?#comment)        这种类型的分组不对正则表达式的处理产生任何影响,用于提供注释让人阅读
        ---------------------------------------------------
        
    9、零宽断言
        用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。
        (?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。如:\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。
        (?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。如:(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。
        
    10、负向零宽断言
        前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,
        如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:
            \b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的单词。如果q出现在单词的结尾的话,像Iraq,Benq,这个表达式就会出错。
            这是因为[^u]总要匹配一个字符,所以如果q是单词的最后一个字符的话,后面的[^u]将会匹配q后面的单词分隔符(可能是空格,或者是句号或其它的什么),后面的\w*\b将会匹配下一个单词,于是\b\w*q[^u]\w*\b就能匹配整个Iraq fighting。
        负向零宽断言能解决这样的问题,因为它只匹配一个位置,并不消费任何字符。现在,我们可以这样来解决这个问题:\b\w*q(?!u)\w*\b。
        零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。
        同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。
        一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。
        
    11、注释
        小括号的另一种用途是通过语法(?#comment)来包含注释。例如:2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)。
        要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。
        
    12、贪婪与懒惰
        当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
        以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。
        有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。
        如:a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
        ---------------------------------------------------
        代码            说明
        *?                重复任意次,但尽可能少重复
        +?                重复1次或更多次,但尽可能少重复
        ??                重复0次或1次,但尽可能少重复
        {n,m}?            重复n到m次,但尽可能少重复
        {n,}?            重复n次以上,但尽可能少重复
        ---------------------------------------------------    

© 著作权归作者所有

共有 人打赏支持
Rksi5
粉丝 1
博文 41
码字总数 50463
作品 0
深圳
程序员
grep搜索utf8文件是否有bom

原网页 http://www.web-jia.com/view.php?a=5 今天在处理后台php文件导出excel出错了 以前是正常的,我本地测试也是正常的 看到报粗是eof 错误,这个php我是用的php自带的服务器所以能直接看...

hongyi1159 ⋅ 2017/03/31 ⋅ 0

慕课网《PHP性能优化初探》学习笔记

//以下内容为慕课网《PHP性能优化初探》笔记整理 1:什么情况下遇到性能问题 语法使用不恰当 用PHP做了不擅长的问题 连接的服务不给力 PHP自身的短板 2:PHP的性能在项目所占比例约占35% 3:...

雨醉风尘 ⋅ 2016/12/06 ⋅ 0

Solr初探(4)——后台数据导入及Document的增删改查

进入Solr后台页面,选择一个核,点击,进入管理标签: 一、添加Document 在Solr初探(2)——域管理中我们已经说过了,id是一个Document必须要包含的field,让我们新建一个,类型为: 在查询...

yuanlaijike ⋅ 04/10 ⋅ 0

天罗地网——Python爬虫初初初探

环境准备 Python 我们使用Python2.7进行开发,注意配置好环境变量。 IDE 我们使用Pycharm进行开发,它和大名鼎鼎的Android Studio、IDEA同出一门——Jet Brains。 关于破解,很无耻的贴两个:...

eclipse_xu ⋅ 2015/09/13 ⋅ 0

爬虫初探-Scrapy

爬虫初探-Scrapy Scrapy 资料 官方文档永远是首选,建议把 tutorial 完整的过一遍。 网址:https://doc.scrapy.org/en/latest/intro/tutorial.html 爬取步骤 我们准备爬取宅男女神排行榜的所...

廖少少 ⋅ 2017/10/25 ⋅ 0

JavaScript 闯关记

《JavaScript 闯关记》之 DOM(下) Element 类型 除了 Document 类型之外,Element 类型就要算是 Web 编程中最常用的类型了。Element 类型用于表现 XML 或 HTML 元素,提供了对元素标签名、...

掘金官方 ⋅ 01/10 ⋅ 0

canal源码分析——项目组成结构

背景 canal项目的介绍及源码请到项目主页:https://github.com/alibaba/canal 去查看。 项目结构初探 下载源码后,我们打开目录看到的是如下一个目录结构。 可以看出canal是一个基于maven构建...

杨武兵 ⋅ 2016/03/15 ⋅ 3

用Python分析豆瓣电影TOP250

既然要分析豆瓣电影TOP250, 那么肯定就要把相关的数据采集下来,比如排名、电影名、导演、主演等信息。 那就肯定使用一下爬虫咯,如果还不会的话,欢迎看之前的文章: Python爬虫学习(一)...

Viljw ⋅ 01/14 ⋅ 0

C# WinForm开发系列 - Regular Expression

正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式文章收集于此,以备不时之需。正则表达式能让更多的复杂的搜索和替换功能变成简单的操作。基本说来,正则表达式是...

长征2号 ⋅ 2017/11/07 ⋅ 0

javaScript的正则表达式 (一)

本篇文章我们就来介绍javaScript的正则表达式 RegExp对象也称正则表达式 一.什么是正则表达式? 正则表达式是一个描述字符模式的对象。可以处理复杂的字符串,正则表达式用于对字符串模式匹配...

博为峰教研组 ⋅ 2016/11/08 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

DevOps 资讯 | PostgreSQL 的时代到来了吗 ?

PostgreSQL是对象-关系型数据库,BSD 许可证。拼读为"post-gress-Q-L"。 作者: Tony Baer 原文: Has the time finally come for PostgreSQL?(有删节) 近30年来 PostgreSQL 无疑是您从未听...

RiboseYim ⋅ 4分钟前 ⋅ 0

Cube、Cuboid 和 Cube Segment

1.Cube (或Data Cube),即数据立方体,是一种常用于数据分析与索引的技术;它可以对原始数据建立多维度索引。通过 Cube 对数据进行分析,可以大大加快数据的查询效率 2.Cuboid 在 Kylin 中特...

无精疯 ⋅ 42分钟前 ⋅ 0

github太慢

1:用浏览器访问 IPAddress.com or http://tool.chinaz.com 使用 IP Lookup 工具获得github.com和github.global.ssl.fastly.net域名的ip地址 2:/etc/hosts文件中添加如下格式(IP最好自己查一...

whoisliang ⋅ 44分钟前 ⋅ 0

非阻塞同步之 CAS

为解决线程安全问题,互斥同步相当于以时间换空间。多线程情况下,只有一个线程可以访问同步代码。这种同步也叫阻塞同步(Blocking Synchronization). 这种同步属于一种悲观并发策略。认为只...

长安一梦 ⋅ 54分钟前 ⋅ 0

云计算的选择悖论如何对待?

人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云计算为...

linux-tao ⋅ 57分钟前 ⋅ 0

Redis 注册为 Windows 服务

Redis 注册为 Windows 服务 redis 注册为 windows 服务相关命令 注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 启动服务 re......

Os_yxguang ⋅ 58分钟前 ⋅ 0

世界那么大,语言那么多,为什么选择Micropython,它的优势在哪?

最近国内MicroPython风靡程序界,是什么原因导致它这么火呢?是因为他功能强大,遵循Mit协议开源么? 错!因为使用它真的是太舒服了!!! Micropython的由来,这得益于Damien George这位伟大...

bodasisiter ⋅ 今天 ⋅ 0

docker 清理总结

杀死所有正在运行的容器 docker kill $(docker ps -a -q) 删除所有已经停止的容器(docker rm没有加-f参数,运行中的容器不会删掉) docker rm $(docker ps -a -q) 删除所有未打 dangling 标...

vvx1024 ⋅ 今天 ⋅ 0

关于学习

以前学车的时候,教练说了这样的一句话:如果一个人坐在车上一直学,一直学,反而不如大家轮流着学。因为一个人一直学,就没有给自己留空间来反思和改进。而轮流着学的时候大家下来之后思考上...

mskk ⋅ 今天 ⋅ 0

压缩工具之gzip-bzip2-xz

win下常见压缩工具:rar zip 7z linux下常见压缩工具:zip gz bz2 xz tar.gz tar.bz2 tar.xz gzip 不支持目录压缩 gzip 1.txt #压缩。执行后1.txt消失,生成1.txt.gz压缩文件 gzip -d 1.txt....

ZHENG-JY ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部