正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang

时间:2024-02-24 19:09:45
所属分类: 正则表达式学习日记 

书名:     学习正则表达式
作者:     Michael Fitzgerald
译者:     王热宇
出版社:   人民邮电出版社
丛书:     图灵程序设计丛书

 
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 封面】
 
前言
 
正则表达式是经过专门编写的文本字符串,它可以用来匹配文件内的字符串集合中符合该模式的所有字符串。通俗的说,就是一个很厉害的、可以查找、匹配和替换任何需要内容的工具。
 
 
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【插入图片 进阶书目】
 
要真正掌握正则表达式,最好的学习方法是亲身实践,而不是做个旁观者。
最好把所有示例都过一遍,按照示例自己操作。
 
 
第1章  什么是正则表达式
 
大多数支持正则表达式的编辑器或工具,其实现正则表达式的方式并不完全一致,其中的一个主要原因,笔者估计该是因为正则表达式的可组合性很强 Composability,只要是掌握了其内核以及构造方法,那么就可以用各种不同的方式来组合,进而匹配出任意的字符。
 
正则表达式处理工具:
1、在线工具
雪炭工具:http://snowcoal.com/tools/regex/reg  #实时匹配效果杰出,可以将匹配结果单独列出,笔者很喜欢
RegExr:https://regexr.com/v1/                 #进行替换操作不错           
 
2、软件
Notepad++
 
 
书的每一章结尾都有一节“技术备忘录”,笔者认为这个方法实在不错,很值得借鉴。其利在两个方面,一则将需要额外添加的拓展延伸知识涵盖在了读者的视野之中,二则虽是可以让读者获得此拓展延伸,但却并非直接在涉及之时便囫囵给出,而是稍提一句如“此主题之拓展,着实厉害,现已附于章尾,可于学完此章后往观之以资补充”便可,尔后继续主题而谈,不致因此拓展而打断正文节奏。
 
自此以降,凡代码,皆以括号括之;凡代码分析,皆以符号>>>导之,以便阅读与理解。
 
若要匹配一串电话号码:707-827-7019,该当如何?
 
(一)字符串字面值 String Literal
 
1.1.【707-827-7019】
 
>>>所谓字符串字面值,也就是同名字说的一般,你字面上是啥,我就输入啥来匹配你。这是我们在平常检索时常用的,如在百度中检索【Mr_Ouyang】,便会将符合这个匹配模式的结果返回给你。
 
(二)字符组 Character Class
 
1.2.【[0-9]】
 
>>>所谓字符组,也就是如同数组一般,指定一个下界(如此处的 0),指定一个上界(如此处的 9),再用“-”将上下界连接起来,表示从下界到上界的范围中的一切数;在上下界之外,需要用方括号“[]”括起来,表示这是一个字符组。
 
>>>方括号,是一种元字符 Metacharacter,又称为 原子 Atom。在正则表达式中,所有的元字符都不参与匹配,因此也将元字符不会参与匹配(可以理解为不会被我们抓壮丁,哈哈~)而保留下来的特性,将它们称为保留字符。
 
>>>字符组,有时也称作字符集 Character Set。
 
1.3.【012789】
 
>>>显然,将字符值放入方括号,可以实现对这些字符的匹配,从而将电话号码707-827-7019给交替高亮出来。
 
(三)字符组简写式 Character Shorthand
 
1.4.【\d\d\d-\d\d\d-\d\d\d\d】
 
>>>\d,是对0-9的数字的字符组简写,其效果等同于[0-9]。
   此处的连字符被作为字面值。
 
>>>字符组简写式,也叫转义字符 Character Escape。但是这个叫法着实容易让人与后面将会介绍的转义字符相混淆,故一般不提倡这样叫。
 
1.5.【\d\d\d\D\d\d\d\D\d\d\d\d】
 
>>>\D,是对\d的转义 Escape。前面说到\d表示数字字符,将其意义转换为相反的,自然便是非数字字符了;虽然这样看来这纯粹是废话,但换种方式阐述,便是\D是表示除了数字之外的其他字符,譬如“.”、“%”、“|”这些,都可以用它来表示,因此此处将代码4中的字面值连字符“-”以\D来代替表示。
 
>>>关于转义,由上面的特殊可以看出其一般规律,便是取反。
   打个比方,已知小明是男的,现在有一位计算机“老师”让大家互相帮忙填一份表格,里面有一栏性别,我们假设可以使用正则表达式,那么如果女生小红给小明填写的是“\男”,那么最后这位老师识别出来的结果便是小明是个女孩;同样的,如果小明给小红的填的是“\女”,那小红在老师眼中也就是小男生了。
 
>>>而更一般的,对那些小写的表达式、命令等,大多都是可以通过转义其相应大写来实现取反的。【此处待补充大写取反】
 
(四)“.” 任意字符匹配
 
1.6.【\d\d\d.\d\d\d.\d\d\d\d】
 
>>>点号是一个通配符,它可以匹配任意字符。这样理解,在抓壮丁这一个行当上,由于点号它比较厉害,谁都难以逃脱它的魔爪,那些壮丁通通都可以被它匹配到然后抓回去,所以敬畏地称它为通配符。
 
>>>但是有一点需要注意,有一个美女它是奈何不了的,毕竟英雄难过美人关。这个美女叫做行起始符,也就是后面将会介绍的脱字符“^”,顾名思义,她可以代表一个行的开始之处。
 
>>>当然了,这位英雄如果吃下了小药丸,纵然那位美女多么妖孽,都难逃英雄的手掌心,会被抓壮丁的(抓到床上,哈哈~)。这个小药丸就是(Dotall),没错,就是这位英雄的伴生装备(英雄名叫Dot),如果需要征服美女“^”时,那就将Dotall选项勾选上,就可以连美女也一同抓住。
 
(五)捕获分组和后向引用 Capturing Group & BackReference
 
1.7.【(\d)\d\1】
 
>>>用括号括住的壮丁,我们就叫做捕获的分组(如此处的(\d)),它既然被我们捕获了,自然不会那么容易放过它,所以我们在原本应该由第三个壮丁来站的位置,通过一个叫做后向引用的方式安排给了这个被我们一举捕获的壮丁了(如此处的\1),此时我们就用这个\1来表示,这里放的是我之前费力捕获到的壮丁,可不一般哦,一个顶俩(甚至更多)!因此,在我们匹配好的结果中,就应该是那串电话号码的前3个字符:707。
 
>>>由此我们可以发现,如果一个壮丁出现了很多次,那么它肯定是要被我们捕获住!毕竟可以省时省力,何乐不为?接下来我们扩展一下这个壮丁队列。
 
1.8.【(\d)0\1\D\d\d\1\D\1\d\d\d】
 
>>>上面的表达式可以匹配出:707-827-7019。
   不难看出,7被我们抓住后,一共被我们使唤了4次,可以说很尽心尽力了,哈哈~真坏!
 
(六)量词
 
1.9.【\d{3}-?\d{3}-?\d{4}】
 
>>>用花括号括住的数字,表示我们要抓的壮丁个数(如\d{3}就代表我们要抓3个数字壮丁)。
   含数字的花括号,是一种量词 Quantifier。
   花括号本身,是元字符。
 
>>>在上面我们还使用了一个新玩意儿,问号“?”。它是助纣为虐的好帮手,我们可离不开它!凡是我们抓壮丁的时候,在后面附上一个问号,便代表我们抓零个或者只抓一个壮丁。乍一看觉得没啥用呀,这么仁慈,还像我们吗?
   其实,李宗吾大佬给我们说过,纵然我们在做些伤天害理、损人利己的事情,也要戴上个悲天悯人、大公无私的面具,不管有多少人能最后看出我们的真实一面,反正能将多少人瞒住就瞒住多少!
   同理,有了这个问号帮忙,等于就是我们给了壮丁们一丝生机(毕竟在他们看来,我们只有一半的几率会抓他嘛,哈哈~),不致于负隅顽抗啦;至于最后是抓,还是不抓...那当然看我们需要不需要这个壮丁啦!需要的话,管他仁义道德,抓他娘的!!不需要的话,那就放过他,还能积点美誉呢。
   在此处,显然我们对于连字符不是很必需,毕竟有的人可能比较马虎,写电话号码时就省去了连字符如7078277019这般,如此的话,抓它还是不抓它,就看到时候我们需不需要它了,如果我们匹配的目标全是没有连字符的如7078277019,那当然不抓它啦;可如果都是707-827-7019这样的,嘿嘿...
 
>>>说到为虎作伥,就不得不再提一下其他两位好帮手了,他们分别是:
   加号“+”,他表示我们可能会从字符组中抓取全部的壮丁,但也可能只抓一个(即匹配一个或多个)
   星号“*”,他表示我们可能会从字符组中一个也不抓;当然啦,既然是为虎作伥好帮手,发起狠来我们都怕的呢,按照这位好帮手的履历,更多的时候他可是全部都抓、一个不留!!(即零个或多个,也即任意个)
 
1.10.【(\d{3,4}[.-]?)+】
 
>>>有没有看花眼?哈哈,这年头,抓壮丁也需要文化,不然壮丁可不老实呢!来,让我们好好学学抓壮丁的文化。
   根据我们上面学的,\d就是抓数字啦。
   {3,4}呢,就相当于量词的一种扩展了,意思就是最少要抓够3个,最多呢抓上4个就行了。
   [.-]呢,相当于我们要从由点号和连字符组成的字符组中抓取它们。
   [.-]?,则表示我们可能会对点号和连字符发善心,有一定可能放它们一马,也就是说,我们据此而抓取的壮丁,可能是如下三种情况:a、只抓了有1个点号  b、只抓了1个连字符  c、他们俩一个都不抓,全放了
   (上述表达式),则表示我们把上面提及的那些家伙都给捕获了!
   (表达式)+,就表示我们把这些家伙给抓住后,最少会抓一次(也就是上面一步刚抓住他们的时候)壮丁,最多的话可能抓上任意次
 
>>>综合起来,就是我们会把这样的三位或者四位的数字给抓起来:
   a、它本身是三位数Or它本身是四位数
   b、它后面跟着一个点号Or它后面跟着一个连字符
   同时满足上述两个特征的,就是我们的刚下的这个套子要捕捉的目标壮丁,就是说我们编写模式,就是一个下套子抓壮丁的过程,不过就是看壮丁是什么样的,我们就编对应的套子罢了;理论上说,我们可以把所有壮丁都抓起来,只要我们能够懂得所有下套子的方法而且会灵活地使用;也就是说,不存在套不住壮丁的套子,如果有哪个壮丁你抓不住,那只不过是你还不会抓住这个壮丁的下套子方法而已,通过学习,你是可以最终征服它的。
 
>>>再回到我们刚刚下的这个套子上,很显然,如果我们一个一个元素地去分析,还是可以很清晰地将套子的构造给搞懂的,再让我们来下一个同样的或者类似的,也是妥妥的没问题。
   但是我们分析后可能会发现,似乎这个套子范围大了些呀,虽然是能够将我们的目标707-827-7019给抓住,但如果还有些我们不要的路人甲乙丙丁在我们目标边上,我们就可能连他们也一同抓了,那可真是吃力不讨好!
   下面我们举几个例子来看看这个套子可能会把哪些路人甲乙丙丁误抓了:
   a、707.827.7019
   b、7078277019
   c、123
   d、1234
   e、123.
   好家伙,比我们还狠呀,可见之前工业革命刚开始的时候劳苦群众抱怨“机器吃人”还真不是虚的,让我们自己亲自上场来抓,估计也就抓了目标707-827-7019就收手了,而这个套子呢(可以理解为一个工具、机器),不仅把我们的目标给抓了,还把许多我们不需要的也给抓了来,效率可真高,也真狠呀,哈哈!!
 
1.11.【(\d{3}[.-]?){2}\d{4}】
 
>>>很显然,这个新下的套子就把上一个套子的误抓的毛病给改掉了,变得更加具有针对性了。
   先抓3个数字。
   再在这三个数字后面抓0个或1个点号或连字符。
   将前两步抓取的3个数字与点号或连字符的组合,重复一遍;等于将这个组合抓上两遍。
   最后再抓取4个数字
 
>>>综合起来,我们发现,我们的目标,不论是规范的707-827-7019,还是不规范的7078277019、或是707.827.7019,就都被我们抓到了。
   这就不致于产生误抓的情况了。这个例子也从一个侧面给我们说明了,对症下药、看人下套的重要性。
 
1.12.【^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$】
 
>>>看的都眼花缭乱了吧?只是为了将一种更加不规范的壮丁(707-827-7019)抓住(其实也就是带了括号的号码啦),我们居然要下这么麻烦的套!
   其实说奇怪也正常,毕竟以我们刚刚下套抓壮丁的技术,已经蛮炉火纯青了,所谓百尺竿头更进一步,便是说我们已经这么厉害了,要想再更进一步,实在是难呀!所以呀,为了将套子再完善些,麻烦是必要的,也是有意义的,哈哈!
 
>>>在分析我们是怎么在捕捉那些目标的基础上,增加对括号目标的捕捉的之前,先来介绍下之前就已照过面的那位美女,脱字符“^”。这脱字符一般有两个作用,第一个是放在开头作为起始符(如此处一般);第二个作用是取反,因为后面会讲到,所以此时便暂按下不表,毕竟还是要给美女保留点神秘感!
 
>>>除了脱字符出场了,还有一个我们耳闻已久的大人物也终于闪亮登场了,那就是转义字符“\”。由于我们要匹配的括号在正则表达式中已经有了其特定的用处(用来抓壮丁,捕获分组,哈哈),所以为了避免那些长着和我们“自己人”一般无二外表的壮丁因为被看错而被我们错误地放过,我们需要先给那些壮丁搞一场冤案,以莫须有的罪名加于其身!!这样子,即使它真是我们“自己人”,我们都会毫不放过地抓起来,更何况我们已经确切地知道它并非自己人了,更是直接一抓而下了!
   也就是说,如果我们需要把那些和自己人长得雷同的壮丁抓起来,不能光是像对待普通壮丁一样直接抓取,因为这样很可能让我们“自己人”的队伍里人心惶惶,担心自己哪天也可能如它一般被我们抓了嘛;而是应该先给它定个莫须有之罪,形式呢,就是在它面上自西北而往东南地划下一刀(什么鬼?哈哈),也就相当于古代给犯人“刺配”一般啦。这样呢,就把它和我们自己的同志给划分开来了,抓起来就不会有那么多羁绊啦!
   在此处,我们就是把左右括号都用斜线转义了。
 
>>>另外,有一个新符号,竖线符“|”,它表示从左右表达式组合中选择其中一个,如此处的便表示:可以选择带括号的,也可以选择不带括号的。
 
>>>最后那个字符,称为美元符,它标志着行结束位置,是不是感觉和前面讲到的行起始符“^”这位美女有些类似?不妨这样想,和美女风花雪月一番,看看电影吃吃饭,总是先要以美女为发端的嘛,没有美女在身边,看电影和吃饭就用不着那么庄严郑重了;而看完电影吃完饭,要怎么样结束这样一个与美女约会的活动呢?当然是付钱啦!!美刀!!嗯,就这样记,哈哈~
 
学到这里,我们已经将正则表达式的大致内容都有了一定了解了,下面我们来看看究竟学了这玩意儿能有啥用。
 
好,假如我现在吃饱了撑的,想要从这篇文章中找出所有我写的那些正则表达式,用来自我陶醉一番。
 
首先,我们要确定要抓取的对象壮丁:就是那些可怜的正则表达式啦;
接下来,我们要分析这些对象壮丁都有些什么特征:由于本文在撰写之初便统一了正则表达式的规范,也就是,首先是一个阿拉伯数字用来表示这个代码是第几条代码,后面跟一个英文点号,尔后是符号【】,我们需要看的代码就在黑框里面呢;
第三步,将我们发现的特征转换为已知的表达式符号:
    在这一步,我们将其分解为两小步。
    a、树典型:这一小步中,我们先找典型的代码,如首、尾以及特殊者,本例中,选取了1、12以及10作为典型,如下:
       1.1.【707-827-7019】
       1.10.【(\d{3,4}[.-]?)+】
       1.12.【^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$】
    b、找规律:
    I.我们发现,开头是从1到12的数字,是不是可以用\d来表示呢?答案似乎是,但好像又不全是,比如说10,11,12这样的,好像表示不了呀,\d不是只能匹配0到9的数字嘛?其实我们完全可以灵活搭配组合,来实现自己的定制化表达式。先放出表示10到19的代码:[1]\d。是不是觉得很讶异?居然还有这样的操作!分组其实也是可以作为字面值的,尤其是在组合的时候,尤为有用,哈哈~既然会表示10到19了,想必将0到99表示出来应该没什么难度了吧?没错,方法是:\d\d,或者是\d{2}。说了这么多,我们总结下这一点的代码:\d|\d{2}
    II.数字之后,跟着一个点号,跟着一个【符号,所以可以将这两个直接用字符值来表示:.【
    III.中间的代码字符我们不知道有多少种符号以及有多少个,那干脆就用可以表示任意字符的点号再配上可以表示任意个数的星号来表示它们:.*
    IV.最后将代码包括在里面的还有一个符号】,所以再添加上一个字面值:】
    上述所言,综合起来便得到了:\d.【.*】|[1]\d.【.*】
>>>注意一点,凡是涉及“|”的操作,若是每一步的后面都有对应的代码,那么就应该将每一个用“|”来表示选择的选项都添上,如此处的,显然\d表示的是0到9序号的代码,而[1]\d表示的是10到19序号的代码,如果我们光顾着给“|”后面的添加后续代码,那么1到9的序号代码将无法得到匹配。一言以蔽之,要雨露均沾,哈哈~
     下面把用雪炭工具来测试的截图贴出,如下:
 
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 示例】
>>>由于上面我们复制粘贴了三条典型代码作为树立的典型,所以我们一共检索出了15条代码,都是整行匹配,厉害吧?如果用Word肯定搞不来,起码我是搞不来的,哈哈~
   那么,我们如何将那些代码全部提出来,而不需要通过像是在Word中那般替换掉符号【】呢?这个我们可以在接下来的学习中学到,此时暂且按下不表。哈哈~
 
接下来我们总结下,我们在这第1章中学习了哪些东西:
 
*  什么是正则表达式?
*  字符串字面值是什么?要怎么样使用?
*  字符组是什么?要怎么样使用?
*  字符组简写式是什么?要怎么样使用?
*  点号是什么?要怎么样使用?
*  捕获分组是什么?后向引用是什么?要怎么样使用?
*  量词是什么?要怎么样使用?
*  问号、加号和星号分别是什么?要怎么样使用?
*  脱字符、竖线符、美元符分别是什么?要怎么样使用?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
1.1.【707-827-7019】
1.2.【[0-9]】
1.3.【012789】
1.4.【\d\d\d-\d\d\d-\d\d\d\d】
1.5.【\d\d\d\D\d\d\d\D\d\d\d\d】
1.6.【\d\d\d.\d\d\d.\d\d\d\d】
1.7.【(\d)\d\1】
1.8.【(\d)0\1\D\d\d\1\D\1\d\d\d】
1.9.【\d{3}-?\d{3}-?\d{4}】
1.10.【(\d{3,4}[.-]?)+】
1.11.【(\d{3}[.-]?){2}\d{4}】
1.12.【^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$】

 
第2章  简单的模式匹配
 
正则表达式唯一的用途,便是在文本中匹配和寻找模式,接下来我们介绍一些简单常见的模式匹配。
 
一般我们在匹配时,都会默认开启全局匹配 Global 选项,这样就不会单在某一行匹配,而是从全文中找到符合我们所下套子的壮丁。
 
在第1章我们讲了字面值、字符组以及字符组简写式,它们可以相互组合搭配,以实现不同的需求。
 
首先,我们先确定一下最低纲领,也可以说是红线,那便是成功匹配出我们需要的结果;
接着,我们要在红线之上追求最省力的实现方法,也就是写最简短的、可以匹配出目标的模式,概括为简短优先原则;
最后,我们才追求其性能上的提升,譬如不需要捕获分组时便不捕获之、不需要回溯时便不采用具有回溯操作的方式等(看不懂吧?这些我们会在后面分别讲到,莫要着急,哈哈~);这便是我们的最高纲领。
 
下面我们来分析一下字符组匹配与字符组简写式匹配的特点:
    a、字符组,可以精确匹配字符,给出哪些字符就匹配哪些字符,灵活、精确匹配,一点也不“误抓”;但使用时需要明确知道有哪些对象,可行性上局限较大
    b、字符组简写式,简短精练;但易“误抓”,不够灵活
 
显然,将多个元素搭配起来组合使用,才是我们实现抓壮丁大业的最佳之策。
 
前面我们知道,数字0到9的字符组简写式是\d,现在我们来介绍下简写式。所谓简写式,便是通过对一个与式子同义的单词或词组的简写来表达一个式子,如\d表示的是数字,而数字的英文单词便是Digit,故而取其首字母表示;同样的道理,其余的简写式也用其同义单词首字母表示,因此,笔者看来,记住其同义单词是记忆简写式的好方法。
 
那么究竟有哪些我们日后可以用得上的简写式呢?如下:
 
*  \d    Digit                    数字字符                 *  \D    非数字字符
*  \w    Word                     单词字符                 *  \W    非单词字符
*  \o    这个我也不知道,哈哈      空字符
*  \a    Alert                    报警符
*  [\b]  Backspace                退格符
*  \c x  Control                  控制符
*  \s    Space                    空白符                   *  \S    非空白符
*  \t    Table                    制表符
*  \n    NextLine                 换行符
*  \r    Return                   回车符
*  \f    暂不知                   换页符
*  \h    暂不知                   水平空白符                *  \H   非水平空白符
*  \v    暂不知                   垂直制表符                *  \V   非垂直制表符
*  \b    Border                   单词边界    

*  \o    xxx                      字符的八进制值
*  \x    xx                       字符的十六进制值
*  \u    xxx                      字符的Unicode值

 
2.1.【\d】
2.2.【[0-9]】
2.3.【[0123456789】
 
>>>上面都表示匹配0-9,单如果我们只需要匹配含有0和1的,则需要代码2.4,如下。
 
2.4.【[01]】
 
>>>从这里我们可以看出字符组在精确匹配字符方面,远甩简写式一条街。
 
2.5.【\D】
2.6.【^0-9】
2.7.【^\d】
 
>>>上面都表示匹配除了0到9意外的所有字符。除了斜杠“\”,我们还发现,脱字符这个美女居然也可以扮演这样的转义的角色,哈哈,这就是我们刚刚没有揭开的面纱,现在这位美女已经完全裸露在你面前啦~
 
2.8.【\w】
2.9.【_a-zA-Z0-9】
 
>>>上面都表示匹配所有单词字符(当然啦,要勾选Global选项啦)。从代码2.9我们可以看出,原来单词就是由下划线“_”、小写字母a到z、大写字母A到Z、数字0到9组合而成的玩意儿呀,哈哈~
 
2.10.【\W】
2.11.【^_a-zA-Z0-9】
2.12.【^\w】
 
>>>上面都表示匹配所有非单词字符,如空格、标点等。
 
2.13.【\s】
2.14.【 \t\n\r】
 
>>>上面都表示匹配所有空白符。从代码2.11我们可以看出,原来空白符就是由空格、制表符、换行符和回车符组合而成的玩意儿。不过有一个要注意,空白符匹配出来的结果,只有空格与制表符能被高亮显示,而换行符与回车符是高亮不来的,但它们确确实实地被我们匹配住了;如果不好理解的话,权且把换行符和回车符当成葫芦娃中那个会隐身术的六娃吧,虽然你隐身了,但我们还是可以把你给抓住的,要不然七星丹又怎么可能炼成呢,哈哈~
 
2.15.【\S】
2.16.【^ \t\n\r】
2.17.【^\s】
 
>>>上面都是匹配所有非空白字符的。
 
2.18.【........】
2.19.【.{8}】
 
>>>上面都是匹配任意八个字符组成的组合的。如词组“The Love”。
 
2.20.【\bL.{2}e\b】
 
>>>上面代码2.20是匹配单词Love的,其中\b是匹配单词边界的字符,可以想见,一个单词它的前面和后面要么便是空格、要么便是标点、要么便是段落标记符、结束标记符,所以我们完全可以通过\b来匹配出由空格、标点等作为边界隔出的单词。
 
>>>代码2.20其实还给我们指出了一个该表达式所具有的特性,那就是特指性 Specificity。因为它首先制定了边界,然后指定了开头字符为L,然后指定了中间字符为两个,最后指定了结尾字符为e并指定边界。
 
2.21.【.*】
2.22.【^\n】
2.23.【^\n\r】
 
>>>上面都是匹配一行中任意个字符的代码。从中我们可以印证我们先前学习的,点号虽然是个大英雄,但也过不了美人关,所以遇到要捕捉脱字符也没辙;而脱字符一般不作为简写式,与脱字符起着同样的表示行标记的简写式主要是换行符“\n”与回车符“\r”,所以如果对他俩取反、将他俩排除在外,那就等于起到了点号匹配除了行标记外所有字符的效果了。
 
接下来我们对前面有过介绍的捕获分组、后向引用做一个扩展。
他们搭配起来可以干嘛呢?能干的多了去了,事实上,他们可是抓壮丁的黄金搭档,他俩尤其擅长浑水摸鱼,偷偷摸摸的就把壮丁神不知鬼不觉地抓了,抓了还不算,还给这被抓获的壮丁穿上了马甲,只要我们想,不管是什么马甲,他俩都能给壮丁披上!这么一听,似乎还是用处不大呀,我们没事给壮丁披马甲干嘛?哈哈,入戏太深啦,让我们来看看实例。
加入我现在重新回过头去看我们第一章那些代码,看了之后发现似乎有哪个地方不太对劲,话不多说,先上图,如下:
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 演示截图第一章】
 
是不是发现没啥问题?再看下一张图,第二章我们的代码,如下:
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 演示截图第二章】
 
现在发现了吧?我如果需要将第一章中所有代码都像第二章那样,在每一个代码序号前都添加一个代码章节的序号怎么办呢?比如说1.1.1.【...】这样的。
 
现在可以请出捕获分组和后向引用这对黄金搭档!
我们打开RegExr网站,单击切换到Replace,然后将文章全部都复制粘贴进去那个文本框,尔后再第一个匹配框中输入:\d[.]【.*】|[1]\d.【.*】  然后你会发现,你已经把所有的第一章代码都给匹配出来了,需要注意的是,由于我们在上一段中给出了1.1.1.【...】,所以,我们匹配出来的结果将由上面的总共15个结果变为16个了,因为这个的后面一小段也是符合我们的规则的。
事实上,如果你把表达式中点号外面的平括号给去掉的话,你将发现匹配的结果居然高达三十多个,原因就出在点号身上。我们知道点号可以表示任意字符,那么匹配的工具自然会将点号作为任意字符来匹配,这样的话,倒不是没有结果来给它额外匹配出来的,比方说,2.9以上的那些代码,如2.10.【...】。观察划线部分,是不是觉得可以匹配?一个数字(1)加上一个可以由点号匹配的任意字符(数字当然也可以匹配啦,所以0到9都可以被匹配到)再加上符号【...】,完美!所以我们就得到了三十多个匹配结果...这当然不是我们想要的啦,所以,最好给点号加上方括号,这样就相当于告诉工具:我这个是点号良民,不是通吃的大英雄!
下面给出截图如下:

正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 演示11】
 
下面我们再对这个改进一下,虽然匹配到了这些壮丁,但我们可不只是想要抓现在的他们,现在还不够格呢,需要给他们披个马甲好看一些!
下面切换到Replace标签,此时再出现一个文本框,我们先将第一个文本框里我们刚刚输入的表达式修改一下,变成被我们捕获的分组:(\d[.]【.*】)|([1]\d.【.*】),理解起来应该不会有难度吧?下面看好啦,在新出现的那个最下面的文本框中输入要替换的表达式,此处我们要达到的目的就是1位数保持一位数的(也就是$1),而两位数的则保持两位数的(即$2),所以我们就在替换框输入:1.$1$2,意思是将我们捕获的两个分组都加上表示章节序号的1和点号,然后第一个分组的按照第一个分组那样、第二个则按照第二个那样。
 
>>>有一个需要注意到的是,我们在前面介绍的后向引用使用的是\1这样的符号,但是有的时候某些在线工具或者软件并不支持这样的形式,这时我们就可以用它的另一个形式$1,即用美元符。
 
下面是关于最终替换的截图以及两个文本框中我们的输入公式:
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 演示12】
 
接下来我们总结下,我们在这第2章中学习了哪些东西:
 
*  正则匹配的最低纲领、进阶阶段以及最高纲领分别是什么?(PS.这些是笔者自己的命名,哈哈,随便起的,你在其他地方可能看不见类似的表述)
*  字符组和字符组简写各有什么特点?为此我们应该如何实现个性化的匹配?
*  文中介绍了的简写式有哪些?现在只需要对它们有一个认识即可,对其用处大可不必求全求备,毕竟它们中的大多数是我们不大可能用得上的,如果日后需要,那就再对它进行检索专门学习,此为任务驱动。
*  什么是Global模式?
*  如何匹配单词和非单词?
*  如何匹配空白字符?
*  可以表示转义的分别是哪两个字符?
*  点号搭配什么可以实现真正意义上的通吃?
*  捕获分组和后向引用在实际生活中可以用来干什么?
*  后向引用的两种方式分别是什么?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
2.1.【\d】
2.2.【[0-9]】
2.3.【[0123456789】
2.4.【[01]】
2.5.【\D】
2.6.【^0-9】
2.7.【^\d】
2.8.【\w】
2.9.【_a-zA-Z0-9】
2.10.【\W】
2.11.【^_a-zA-Z0-9】
2.12.【^\w】
2.13.【\s】
2.14.【 \t\n\r】
2.15.【\S】
2.16.【^ \t\n\r】
2.17.【^\s】
2.18.【........】
2.19.【.{8}】
2.20.【\bL.{2}e\b】
2.21.【.*】
2.22.【^\n】
2.23.【^\n\r】

 
第3章  边界
 
这章我们要学习的是边界,顾名思义,行与行之间、单词与单词之间等等,都是边界在起着作用。边界又叫做断言 Assertion,也就是将大段的言语或者小段的言词断开的东西。
话不多说,先上代码。
 
3.1.【^How, *Country\.$】
 
>>>显然这个表达式是匹配这么一个内容:以How搭配一个逗号开头,中间字符任意,再以Country搭配一个点号结尾。
点号前面的那个斜杠是起的将点号这一通吃的大英雄转义从而只识别出点号(也就是作为一句话的结束的标点符号)的作用。
其中,脱字符“^”便是行起始符啦,它就是行开始的边界;而美元符“$”便是行结束符,是行结束的边界。无需赘言。另外,脱字符与美元符这样的断言,又被称为锚位符 Anchor,意为锚定一个起始或者结束的位置的符号,起着与海船上的锚一样的重要作用。
那么给这个表达式加上脱字符与美元符有什么用处呢?
那就是将一行给匹配出来,是的,只匹配一行!如果我们不用行起始与结束符,那么如果存在首段首与尾段尾都符号模式的情况,则整个文档都会被匹配到。
当然啦,我们一般使用脱字符和美元符来将匹配限定到行的时候,还需要勾选另外一个选项:多行 Multiline。原因也很好理解,如果不勾选多行,那工具不就自动认为我们需要将整个文档作为一行来进行匹配、从而可能从全文来匹配嘛?此种情况下,Global可以勾选也可以不勾选,无甚差别。
 
3.2.【\bthe\b】
 
>>>\b是对单词边界的匹配,它属于零宽度断言 Zero-Width Assertion,也就是不会占用位置不占用空间的绿色环保的符号,哈哈~
这里,表达式匹配的就是一个the单词,如果是“I Love Miss Liu, the beautiful girl in my Life. I bought a ring, then I\'ll give it to her."则里面Miss Liu后面的the我们可以匹配出来,但那个then,虽然也是有the,可是由于其后面并非一个边界,而是仍有字符存在,故而不对其匹配。
 
3.3.【\Be\B】
 
>>>显然\B是对\b的取反,也就是匹配非单词边界,比如单词或字符串中的字母、数字等。这个代码中,将会对存在于单词、字符串中的非开头和结尾的e进行匹配,当然了,它只匹配e这么一个字母,而不会将其旁边的其他字符匹配。
 
3.4.【\Q.^$*+|?(){}[]\-\E】
 
>>>上面这个表达式是不是看起来很凌乱?那就对了。当我们需要大段的输入一些要么很凌乱、要么是正则使用的符号(如^或者*)等的时候,如果一个一个地添加转义字符,那岂不是特别累!这个方法,就是用来对大段的字符进行转义的。把字符放入\Q与\E中间即可,多简单呀~
通过这个方法,我们就可以轻松地使用元字符(还记得元字符吧?哈哈)的字面值啦。
 
接下来我们来讲一下如何为一个纯文本添加Html标签,学会了这个,以后如果要做网页那可就轻松地多了。
 
首先我们打开RegEx网站,然后在第二个文本框中输入“这是一个实例文件,用来演示添加Html标签的。”,然后在第一个文本框中输入表达式“^(.*)$”(也就是匹配整行),再在第三个文本框中输入:
 
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
【此处需要插入图片 Html替换标签代码】
这样就完成了一个对标题的标签添加,所用的知识,其实我们在先前也已经接触过了,就是边界、捕获分组以及后向引用啦。下面将截图贴在下面:
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 演示标题插入】
是不是觉得很简单呢?其他Html文档的部分也是可以通过这样的方式来实现相应的标记的添加的,具体请自行根据实际情况进行摸索。
 
接下来我们总结下,我们在这第3章中学习了哪些东西:
 
*  边界(或称断言)究竟是什么?
*  脱字符与美元符作为边界起着什么作用?锚位符是什么?
*  Multiline是什么?它有什么作用?
*  单词边界与非单词边界起着什么作用?
*  如何轻松地大段使用元字符?
*  如何用正则表达式将纯文本转化为Html文本?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
3.1.【^How, *Country\.$】
3.2.【\bthe\b】
3.3.【\Be\B】
3.4.【\Q.^$*+|?(){}[]\-\E】
 

 
第4章  选择、分组和后向引用
 
在本章,我们会更多地使用选项(比如我们前面已经接触过的Dotall、Global、Multiline),因此,我们还是先交代下要使用的工具为妙。
在本章的练习,尽量在RegExr网站来进行。
同样的,话不多说,我们先上代码:
 
4.1.【(the|The|THE)】
 
>>>这个表达式是让工具将符合模式中这三种样式的都给匹配来:the、The和THE。其中,竖线符“|”表示选择,即从给出的模式中选择一个出来,一般工具是按照从左到右的方式来匹配的,也就是说会先在文本中检索是否有the,如果没有,那就再检索The,再没有,就检索THE,直到找到一个符合的为止,当然啦,全都找到也是可以的。
 
>>>事实上,我们会发现,这么三个词,主要的差别也就是单词字母的大小写而已,如果就为了这么一个简单的问题就要写一大串的表达式,也未免过于冗长。所以工具提供了另一种小药丸给我们,可以让我们轻松许多:忽略大小写   Ignore Case。
 
4.2.【the】
 
>>>此时如果我们勾选了Ignore Case,那么只要键入这么一个简单的表达式就可以实现代码3.1的功能了,你可以亲手去实践一下。
 
下面我们再来介绍一个重要的概念。
子模式 Subpatattern,是指分组中的一个或者多个的分组,我们完全可以把子模式理解为分组中的分组、模式中的模式。抽象吧?我们来用3.1的代码来解释一下。
(the|The|THE),就是一个分组,这个分组当中又嵌套着3个分组,所以我们可以将the、The和THE都叫做子模式,他们的父模式就是用括号括起来的这么一个模式。
上面这样的子模式,根据能否匹配到第二个子模式(也就是The)是否取决于第一个子模式(即the)的匹配,我们可以将其称作“不依赖型子模式”,也就是说,不管文本中有没有the存在,只要存在第二个子模式The,那么就一定能将The匹配到。
下面介绍一个“依赖型子模式”。
 
4.3.【(t|T)h(e|eir)】
 
>>>代码3.3中一共存在两个子模式(当然啦,这两个子模式之中又分别有两个它们各自的子模式),第二个子模式(e|eir)能否得到匹配,就必须看第一个子模式(t|T)能否得到匹配。比如说,如果文本中存在the,那么第二个子模式就可以匹配到,如果文本只有ahe,bhe...zhe,唯独就是没有the和The,那么第二个子模式纵然是在文本中存在,也无法得到匹配。
这就是依赖型的子模式啦~
 
括号对于子模式而言并非必须的。我们再来看下面的代码:
 
4.4.【\b[tT]h[ceinry]*\b】
 
>>>这个模式存在两个子模式,而且有单词边界,所以最后其可能匹配出来的结果会有:the The thee thy thence等单词。
 
>>>从代码3.4我们发现,字符组其实也是可以作为子模式来使用的。鉴于字符组所起的作用与子模式无异,故而本书作者认为完全可以将字符组归于子模式之行列,笔者也认为是可以的,毕竟只要我们能切实地使用上,管它姓资还是姓社?
 
前面我们大量的介绍了捕获分组,但是我们却没有对他做一个全面的审视,现在是时候给他做个CT,看看他哪里好、哪里坏啦!
 
捕获分组因为要先将壮丁抓住,然后把它给关在我们的房间中,所以必然会挤占我们本就不算太大的空间,为此,我们要抓壮丁的活动就难免因为腾挪不便而颇受掣肘。
通俗的说就是,捕获分组要将数据抓取然后暂时存储在内存中,以便后续的调用(即后向引用),所以会占用内存,进而影响到性能。所以,虽然捕获起来对后向引用很是方便,但如果我们根本就不打算在日后用上他,那就干脆别捕获啦!为此,正则表达式中特意弄出了一个替代选择:非捕获分组 Non-Capuring Group。下面我们用代码来解释一下:
 
4.5.【(?:the|The|THE)】
 
>>>为分组的开头添加一个问号和冒号,就相当于给工具一个提示:记住了,我要把这个分组给匹配出来,但我不要你把他们都抓住,因为这样我速度贼慢,我可受不了!
现在是否明白了什么叫非捕获分组了呢?不明白没关系,日后你会理解的。
 
4.6.【(?>the|The|THE)】
 
>>>在分组的开头添加一个问号喝大于号,实际上就是使用了一个原子分组 Atomic Group,这原子分组也是非捕获分组的一员,不过呢,他可以将回溯操作关闭掉,也就因此可以提升运行的性能了。当然啦,这个我们还是不必太多关注的,起码目前来说是这样的,毕竟这应该是那些高级人员才需要去完善的“细微末节”。
另外,关于这里提到的回溯操作,我回在后续的内容中解释给大家。
 
接下来我们总结下,我们在这第4章中学习了哪些东西:
 
*  如何用竖线符进行选择操作?
*  子模式是什么?它分别有哪两个类型?
*  字符组是子模式吗?
*  捕获分组有什么地方“不好”?
*  非捕获分组是什么?要怎么样去使用它?原子分组是什么?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
4.1.【(the|The|THE)】
4.2.【the】
4.3.【(t|T)h(e|eir)】
4.4.【\b[tT]h[ceinry]*\b】
4.5.【(?:the|The|THE)】
4.6.【(?>the|The|THE)】
 

 
第5章  字符组
 
字符组有时也被称作方括号表达式  Breaketed E^x^p^r^e^ssion。
 
5.1.【a-f】
5.2.【3-6】
 
>>>代码5.1匹配的是从a到f的字母,代码5.2匹配的是从3到6的数字,很简单是吧?这说明你前面的基础夯地很实哦,鼓励一下!
 
下面我们来试着匹配从10到19的偶数。
 
5.3.【\b[1][24680]\b】
 
>>>是不是也觉得是个小Case?哈哈,那我只能说你的基础可真牢!点赞。
 
下面我们再做延伸,如何匹配0到99的偶数呢?
 
5.4.【\b[24680]\b|\b[1-9][24680]\b】
 
>>>想必理解起来也不会有多大的难度吧?重要的是想象力,哈哈~没有你抓不到的壮丁,只有你想不到的抓壮丁的套!
 
5.5.【[\w\s]】
5.6.【[_a-zA-Z \t\n\r]】
 
>>>从代码5.5我们可以发现,字符组中也是可以使用简写式的,5.5的作用就等同于代码5.6。
 
5.7.【[^aeiou]】
 
>>>用脱字符在字符组中取反,这个我们也学过,现在你还记得吗?如果忘了的话可以回过去再复习下,这可是很有用的哦。
 
5.8.【[0-3[6-9]]】
 
>>>是的,你没有看错,字符组之中居然嵌套了一个字符组!这是搞啥呢?
上面的代码5.8的作用是匹配[0 1 2 3 6 7 8 9],是不是发现了什么?没错,就是取并集呀!记住哦,嵌套使用字符组,即可取并集哦。
 
5.9.【[0-9&&[^4-5]]】
 
>>>代码5.9就是取差集的表达式啦,实际上就是减的操作,不过就是要多加上两个&而已。
上述代码5.9的作用与代码5.8一样哦,不知道你可猜对了呢?
 
其实后面还有一个知识点,POSIX字符组,但是鉴于不是特别常用和实用,所以笔者认为无需过多关注,故而不予陈述 ,若读者有兴趣,大可于互联网上搜索来学习。
 
接下来我们总结下,我们在这第4章中学习了哪些东西:
 
*  如何匹配0到99的偶数?
*  怎样实现字符组取反呢?
*  如何给字符组取并集?
*  如何给字符组取差集?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
5.1.【a-f】
5.2.【3-6】
5.3.【\b[1][24680]\b】
5.4.【\b[24680]\b|\b[1-9][24680]\b】
5.5.【[\w\s]】
5.6.【[_a-zA-Z \t\n\r]】
5.7.【[^aeiou]】
5.8.【[0-3[6-9]]】
5.9.【[0-9&&[^4-5]]】

 
第6章  匹配Unicode和其他字符
 
鉴于该章节内容不甚实用,且较为繁杂艰涩,不予讲述,若读者有兴趣,不妨自行检索学习。
 

 
第7章  量词
 
前面我们提到的量词有哪些呢?还记得那三个为虎作伥的小能手吗?分别是问号、加号和星号。接下来我们给他们做一个传记。
 
7.1.【9.*】
 
>>>星号量词,我们都知道是可以匹配任意个字符的。但其实它本身是贪心的 Greedy,每一次匹配它都会先将全部文本都“吃下去”,如果将需要匹配的字符串找到了,那就会将结果返回给我们,但如果没有找到,它就会将刚刚一口气吃下去的文本都给“一点一点地吐出来”(有没有感觉很像骆驼的胃?哈哈),再从吐出的内容中寻找,直到找到或者真的找不到,才会放弃寻找了。事实上,这个过程就是我们在先前提及但未展开的回溯操作。回溯,也就是从开头跑到了终点,可是因为没有在旅途中找到需要的东西,所以又从终点跑回开头再次寻找(是不是跟我们丢了东西后去一个地方反复寻找的情况很是类似?哈哈)。
 
>>>尽管回溯操作有助于将我们需要的东西找到,但回溯操作却也有着极大的局限,那就是性能的拖慢,这也很好理解,就好比我们去找东西,如果我们反反复复地在一个地方来回寻找,当然比起只是从这个地方找了一遍就不找了要花更多的时间啦。
 
7.2.【5?】
7.3.【5??】
 
>>>代码7.2是要查找0个或者1个数字5,所以如果文本中存在数字5,那么就会自动将5给匹配出来
 
>>>可是代码7.3却不会这样,它的结果就是,就算文本中存在数字5,他也不给你找出来。是不是觉得他很懒?没错,问号就是懒惰的,如果有的选择,他就会选择最少的那个来做,哈哈~
下面我们再来通过几个代码来加深一下懒惰的问号是怎么样的。
 
7.4.【5+?】
7.5.【5*?】
7.6.【5{2,5}?】
 
>>>代码7.4中,由于加了一个问号,使得5+变成了懒惰的匹配了,所以原本是要匹配1个或一个以上的数字5的,立刻就变得只能匹配出一个5,就是因为懒惰的量词选择了最省事最轻松的匹配(即此处的匹配1个)
 
>>>代码7.5中,也是因为懒惰量词,所以最后只能匹配到0个5,因为星号是让匹配0个或更多个的,既然可以匹配0个,那么懒惰的量词就干脆只匹配零个就交差了事啦
 
>>>同样的道理,代码7.6就只能匹配到2个数字5啦
看到这里,想必你对懒惰量词应该有了一定的了解了吧?
 
下面介绍另一种量词,它可是和星号持相反政见的政敌哦。
 
7.7.【0.*+】
7.8.【.*+0】
 
>>>键入代码7.7,你会发现以0开头的所有的数字都被选中了,是不是觉得很星号其实还是一样一样的?且往后看。
 
>>>再键入代码7.8,你会发现居然没有任何结果被匹配出来!这是为什么呢?
原因就出在以加号结尾的量词是占有欲很强的,一旦吃进了他肚子里,再想让他像贪心量词一样再吐出来重新搜索一遍,那几乎是不可能的,“凡是进了我的肚子的,就是我的了,休想让我再吐出来,哼!”这就是加号占有量词的心声,哈哈~
由于键入代码7.7之后,我们已经让全部文本都被加号吃进了肚子,此时再键入代码7.8要查找的话,就没办法了,因为他已经把所有文本都吃进去了,不再让我们再匹配了,所以也就自然没有匹配的结果给我们返回啦。
之所以会吃进去就不再吐出来,其实是因为他不会进行回溯操作,所以,自然加号便是星号的政敌啦!哈哈,这样想会不会脑洞有点大?(“这位作者,这样污蔑我们俩,我和你什么仇什么怨?”加号和星号如此腹诽笔者道。)
 
7.9.【7{1}】
7.10.【7{1,9}】
7.11【7{1,}】
 
>>>这里我们又看见了特定次数量词匹配的身影啦,呃?不对,怎么后面来了一个奇奇怪怪的哥们?代码7.11你给我出来!干嘛呢你?怎么不符合规范啊?你的上界哪去了?被你吃了??
其实呀,代码7.11虽然看似在逗号后面没有上界,但实际上也是有一个上界的,那就是数学上的无穷大,哈哈,也就是说,这哥们的上界就是——无上界!瞧瞧,口气多大呀,哈哈,让我们来看看代码7.11到底匹配的是什么?
哇塞塞,居然能匹配自数字1以上的所有数字,厉害厉害!
 
上面我们介绍的就是特定次数匹配的几种形式啦,读者可以自行发散开来、推而广之哦。
 
接下来我们总结下,我们在这第7章中学习了哪些东西:
 
*  什么是贪心量词?
*  什么是回溯操作?
*  什么是懒惰量词?
*  什么是占有量词?
*  贪心量词与占有量词有什么区别?
*  特定次数量词有哪三种形式?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
7.1.【9.*】
7.2.【5?】
7.3.【5??】
7.4.【5+?】
7.5.【5*?】
7.6.【5{2,5}?】
7.7.【0.*+】
7.8.【.*+0】
7.9.【7{1}】
7.10.【7{1,9}】
7.11.【7{1,}】
 
第8章  环视
 
环视是一种功能非捕获分组,是一种零宽度断言(还记得这个是什么吗?之前在讲到边界的时候我们也提到了一个,如果忘记了,可以回过去看看哦),因此环视并不会“占位置”,因为它本身就是没有宽度的,哈哈,这不是废话嘛~
 
环视分为正前瞻、反前瞻、正后顾、反后顾。
 
我们先上图,用实例来看看什么是正前瞻。如下图所示,我们给定的文本中有许多关键词,但我们却只想要含有一定特征的关键词,比如说这个关键词后面必须跟着一个固定的字或者前面必须跟着一个固定的字,这样的关键词,我们才需要。这个时候,环视就很有用处了,他可以通过后面或前面的字来匹配我们所需的独一无二的关键词,比如我这里想要的就是后面跟着“ Is”的"Mr_Ouyang",凡是跟着其他的,都不是我想要的。

正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 正前瞻演示】
从图片中,我们可以看出,正前瞻的代码如下:
 
8.1.【Mr_Ouyang(?= Is)】
 
>>>正前瞻,就是我们要检索的关键词加上用括号括住的问号加等于号再加上关键词后面那个固定字符。最终它检索出来的,就是我们检索的关键词啦,当然,它不会把后面的固定字符一同匹配出来,这就比起我们之前学习的知识要不同,之前的,顶多就是连固定字符一同匹配,届时还需要再将固定去掉,麻烦!
 
8.2.【Mr_Ouyang(?!Is)】
 
>>>反前瞻,同样是检索关键词,只不过这次我是不需要跟着某个固定字符的关键词了,这样我们就可以使用反前瞻,这在事实上就是对正前瞻的取反,代码8.2便是对代码8.1效果的取反。
 
8.3.【(?<=So )Handsome】
 
>>>正后顾,原理类似,只不过是根据关键词前面的固定字符来查找后面的关键词,大同小异罢了。代码8.3效果如下图所示,将前面一个单词为“So ”的关键词Handsome给匹配出来了,而后面的Handsome,由于不符合前面那个固定字符,所以没有被匹配。
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 正后顾演示】
8.4.【(?<!So )Handsome】
 
>>>反后顾,原理类似,是对正后顾的取反。代码8.4的效果是对代码8.3的取反。
 
其实环视还是很好理解,而且还是很有作用的。那么它有什么用呢?
现在,你是办公室一个小职员,办公室主任扔给你一个任务:那个小欧啊,赶紧的,现在这份公司高层会议的会议记录给你,你给我赶紧把里面Mr_Ouyang老总的发言都给我找出来,急用!记住了,别漏了哦~
拿到任务一看,傻眼了,会议记录一共一百多页,天!
其实大可不必如此煎熬,用文字扫描工具将会议记录扫描为文字,尔后将所有文字用正则匹配,下面做个演示,打开雪炭工具网页,检索:Mr_Ouyang(?=说).*。具体如下图所示:
正则表达式学习日记_《学习正则表达式》笔记_Mr_Ouyang
 
 
【此处需要插入图片 环视截取演示】
 
或者,还可以用来在老师给出的课件或者其他文本中找关键词及相应解释文段,牛气吧?哈哈~
 
接下来我们总结下,我们在这第7章中学习了哪些东西:
 
*  什么是正前瞻?
*  什么是反前瞻?
*  什么是正后顾?
*  什么是反后顾?
*  环视可以在实际生活中如何应用?
 
下面将利用雪炭工具获得的代码全部贴到下方,以便回顾所学:
 
8.1.【Mr_Ouyang(?= Is)】
8.2.【Mr_Ouyang(?!Is)】
8.3.【(?<=So )Handsome】
8.4.【(?<!So )Handsome】
 
 
第9章  用Html标记文段
 
鉴于该章节与前述相比并无新知识点,只不过是介绍了几个用来进行正则表达式检索的工具如Sed、Perl等,并介绍使用它们来进行纯文本的Html标记添加,与我们目前的使用并无太大关联,故而不予陈述。
 
 
第10章  初级班毕业了
 
本章讲的是,我们通过前面9个章节的学习,已经大致掌握了正则表达式的基本用法,至于进阶或者高级用法,便需要我们在日后的实践中遇到难题并进行相应学习来提高了。这一点,笔者很是赞同,就是需要实践驱动!
 
之前许多人便宣称,要想成功,最好的老师就是兴趣,你必须要培养起对他的兴趣,只有这样你才有动力去学,才能成功。
 
笔者之前也是如此认为的,但现在却不敢再苟同之。
 
笔者以为,真正让你走向“成功”的,恐怕并非兴趣,而是需求。兴趣,是让你想要去提高,自觉地想要去完善自己;而需求,是让你不得不提高,虽然是*、但却很高效的能促使你完善自己。
 
基于此,笔者提倡,如果要学习一门技术或者说知识,大可不必等全部都掌握了再去实践,完全可以在掌握了基础后便去用此技术、知识去闯荡,直到闯到一个程度、遇到你的瓶颈,再去充电,专门性的去学习,这样想必会更加有助于你的自我完善。当然,笔者自己也在如此地实践。
 
最后,三天的写作终于完成了,想笔者这本书才看一天,结果居然断断续续地写了3天才将本文写完,真是不易。原本是兴致勃勃的,尤其是看到有一些读者看见本文,并予以一定互动,让笔者顿时鸡血满满,心中极其享受本文的写作。可是后面慢慢的就由热转凉,一方面是因为每天上课的时间比较多,另一方面是互动渐少,兴趣也便冷了下来,再加上笔者愈发觉得需要打好基础,所以想要多看看书,而不是看一本书就写一篇文(虽然笔者以为这样做着实很有帮助),所以到最后,就是抱着赶紧将本文完结,然后就暂时不写博客了,待这回多看些书,日后再回来写,想必那时笔者该有一个蜕变了罢?
 
我很期待...
 
Mr_Ouyang
2017-11-16 21:28
 
最后,将本文出现的所有代码都附在下面,以便学习巩固(想必你还记得我们之前每一个章节后都会附上章节代码吧?这样的话,匹配出来的所有代码岂不是会重复一遍吗?没错的,的确会重复,所以你猜猜看我是怎么样解决的呢?好吧,本来想装个酷的,结果很逊的是,我也解决不了,哈哈,最后百度检索了一下,找到了一个解决方法,用Notepad++,然后再替换的查找框中键入代码:^(.*?)$\s+?^(?=.*^\1$),勾选匹配新行,然后全部替换即可实现去重。正是这样的有任务驱动然后自行检索学习,一步一步地促使着我们在技术的路上不断狂奔;经验作者也是如此,这也是他在工作中遇到需求尔后遍寻无合适之法,最后于Google中找到经验的。好啦,说了这么多,下面放代码:
 

 
1.1.【707-827-7019】
1.2.【[0-9]】
1.3.【012789】
1.4.【\d\d\d-\d\d\d-\d\d\d\d】
1.5.【\d\d\d\D\d\d\d\D\d\d\d\d】
1.6.【\d\d\d.\d\d\d.\d\d\d\d】
1.7.【(\d)\d\1】
1.8.【(\d)0\1\D\d\d\1\D\1\d\d\d】
1.9.【\d{3}-?\d{3}-?\d{4}】
1.10.【(\d{3,4}[.-]?)+】
1.11.【(\d{3}[.-]?){2}\d{4}】
1.12.【^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$】
 
--------------------------------------------------------------------------------------------------
 
2.1.【\d】
2.2.【[0-9]】
2.3.【[0123456789】
2.4.【[01]】
2.5.【\D】
2.6.【^0-9】
2.7.【^\d】
2.8.【\w】
2.9.【_a-zA-Z0-9】
2.10.【\W】
2.11.【^_a-zA-Z0-9】
2.12.【^\w】
2.13.【\s】
2.14.【 \t\n\r】
2.15.【\S】
2.16.【^ \t\n\r】
2.17.【^\s】
2.18.【........】
2.19.【.{8}】
2.20.【\bL.{2}e\b】
2.21.【.*】
2.22.【^\n】
2.23.【^\n\r】
 
--------------------------------------------------------------------------------------------------
 
3.1.【^How, *Country\.$】
3.2.【\bthe\b】
3.3.【\Be\B】
3.4.【\Q.^$*+|?(){}[]\-\E】
 
--------------------------------------------------------------------------------------------------
 
4.1.【(the|The|THE)】
4.2.【the】
4.3.【(t|T)h(e|eir)】
4.4.【\b[tT]h[ceinry]*\b】
4.5.【(?:the|The|THE)】
4.6.【(?>the|The|THE)】
 
--------------------------------------------------------------------------------------------------
 
5.1.【a-f】
5.2.【3-6】
5.3.【\b[1][24680]\b】
5.4.【\b[24680]\b|\b[1-9][24680]\b】
5.5.【[\w\s]】
5.6.【[_a-zA-Z \t\n\r]】
5.7.【[^aeiou]】
5.8.【[0-3[6-9]]】
5.9.【[0-9&&[^4-5]]】
 
--------------------------------------------------------------------------------------------------
 
7.1.【9.*】
7.2.【5?】
7.3.【5??】
7.4.【5+?】
7.5.【5*?】
7.6.【5{2,5}?】
7.7.【0.*+】
7.8.【.*+0】
7.9.【7{1}】
7.10.【7{1,9}】
7.11.【7{1,}】
 
--------------------------------------------------------------------------------------------------
 
8.1.【Mr_Ouyang(?= Is)】
8.2.【Mr_Ouyang(?!Is)】
8.3.【(?<=So )Handsome】
8.4.【(?<!So )Handsome】