学习正则表达式

正则手记_本人自学实践的一部分笔记+个人粗浅的理解

注:正则表达式,不是程序员的专属工具,我等非程序员也可以拿来提高工作效率。以下内容主要为读书笔记,加上一些自己的理解,通过配图,应该有助于理解。

正文:

正则,中文全称:“正则表达式”;英文全称:Regular Expressions,简称:Regex。

定义:简单说,它就是一个字符串,是一种特殊形式的文本模式。

优点:具有超强结构描述能力的形式化表达方法。

怎么个超强?

简单说,你在一般的文字处理软件中,例如Word,你输入“1”,你就只能找到1;它不会为你找到“2”或者其他数字;你输入“abc”,它也只能找到abc或ABC或者aBC等等,不会找到def或者其他的字母组合。那,有没有什么工具是可以一次找到我想要的全部数字或字母(组合)呢?有!就是正则表达式。当然了,正则表达式的威力绝对不仅仅是我刚刚说到的这么一点点。它的威力取决于你对它的学习,了解和使用的程度。

谁需要用正则表达式:程序员,如果一个程序员(本人不是),不懂正则表达式,效率就会大打折扣。

我不是程序员,正则对我有用吗?答案是:YES!

可以这样说,不会正则的程序员不是合格的程序员;不会正则的文本处理者也不大可能是一个高效的文本工作者。

“我不是程序员,工作的主要内容也不是大规模的文本处理,平时工作就用一下excel,还需要正则吗?”答案还是:YES!

既然正则这么好用,

那还等什么?!开始学!!

首先,学习正则的书籍有哪些?

《正则表达式必知必会》(Ben Forta,翻译:杨涛等)_入门级,菜鸟的选择;

《正则指引》(作者:余晟)_提升级,概念梳理的非常好!内容实在!

《精通正则表达式》(作者:Jeffrey E.F. Friedl;翻译:余晟)_精进级,必读!非程序员,至少需要阅读前4章,最好吃透前6章;

《正则表达式经典实例》(Jan Goyvaerts、Steven Levitban;翻译:郭耀,迟骋 审校:余晟)_“快餐级”。可以看作是学习正则后的速查手册。

Windows系统下常见的支持正则表达式的软件(实际上有很多,不一一举):

Notepad++:免费;

Emeditor:收费,网上容易找到;

Editpad:专业版收费,新版网上不容易找到;此为本人最爱。可以用它的lite版,免费的;

作者:Jan Goyvaerts,他公司还有如下优秀软件:

Regexbuddy、Powergrep、Acetext等,其中,Regexbuddy是学习正则表达式的绝佳帮手!

上面的软件,正则功能非常强大,但是没有像Word那样的文字处理功能。那有没有像word那样具备文字处理能力,又支持正则功能的软件?

有!就是libreoffice!它的文字处理以及电子表格都是支持正则表达式的,可谓两全其美。它还有其他优势:开元免费而且不带广告,还是多国语言的,还可以安装到U盘,随身携带使用。实在太“帅”了!

上面讲的是基本的概念、正则相关的书籍和可能用到的软件。下面上“干货”。

正则基本内容:

1.元字符(12个)

2.字符组(匹配单个字符)

3.排除型字符组

4.量词:?、+、*、{m,n}及变体

5.多选结构

6.分组及反向引用

7.断言(精确匹配)

8.环视(位置匹配)

9.回溯及正则应用原理(重点和难点)

--------------------------割一下-----------------------------------

元字符(12个)

括号类:(、 )、 [、 { (4个)

量词类:?、+、 * 、. (4个)

其他类:^、$、 \、 | (4个)

知识点:1.元字符是构建正则引擎(Regex Engine)的重要部件;可以这样说,没有元字符,就没有正则表达式;完整的正则表达式就是两部分构成:元字符+普通文本字符;2.元字符本身具有特殊含义;3.元字符本身的匹配需要进行转义(escape)__在元字符前加斜杠\,比如:\(,或者\.或者\\等等;注意:这些元字符,如果放入[ ]中,它们就不再是元字符,而是普通的字符。

字符组(匹配单个字符

常见的字符组(字符之间是“或”的关系)及简写(注意大小写):

[ \f\n\r\t\v]=\s,方括号里的第一字符是空格\f是换页符,\n是换行符,\r是回车符,\t是制表符(Tab符),\v是垂直制表符;

[0-9]=\d:匹配从0-9的单个数字字符,书写顺序只能是0-9,不能是9-0,而且必须放[ ]括号内;比如,匹配10位长度的数字,可以写成[0-9]{10},等价于\d{10};{10}是量词限制,后面讲;

[a-z]或者[A-Z]:前者匹配从a到z的小写字母字符,后者匹配从A到Z的大写字母字符,同样要注意顺序,不能倒过来写;

匹配单个中文字符:[\u4e00-\u9fff]。匹配多个中文字符,用量词。

而且,如果不需要区别大小写时,可以用修饰符(?i)来打开“不区分大小写”功能,用(?-i)来关闭“不区分大小写功能”,也就是打开区分大小写功能。Q:gr[ae]y可以匹配的单词?A:可以匹配gray和grey。

简写:常用的简写有\d\w\s

\d和\D互补:\d匹配单个数字字符,那\D就不能匹配数字字符;

\w和\W互补:\w匹配可以单个数字,字符(大小写),下划线,中文字符等,\W就不能匹配它们;

\s和\S互补:\s匹配单个空格,\S就不能匹配空格,而是匹配单个非空格字符。

排除型字符组(排除单个字符)

[^…]:表示“匹配一个未列出的字符(match a character that’s not listed)”而非“不要匹配列出的字符(Don’t match what is listed)”。这两句话的区别在于:

前者强调:一个字符组,即使是排除型字符组,也需要匹配一个字符,匹配一个除了“排除型字符组中所有字符”以外的字符。

后者暗示:这里不出现任何字符也可以。

量词:?+*{m,n}及变体

首先要明确:量词只作用于前面的元素。常见量词范围如下(取自余晟老师的正则指引,非商用!):

匹配优先量词、忽略优先量词

匹配优先量词:上表中的?、+、*、{m,n}及其变体都是匹配优先的;

忽略优先量词:??、+?、*?是忽略优先,就是在?、+、*后加?后,匹配优先量词就成了忽略优先量词。

匹配优先、忽略优先在后面的回溯及匹配原理部分,会显得十分重要。

多选结构

多选结构额样式:(...|...|…),括号内竖线|分割多个子表达式(多选分支)。

匹配:优先选择最左的匹配结果,所以要注意多选结构的排列顺序。

如下图:

注意事项:

多选结构的级别很低(效率问题),能用字符组解决的问题,最好不要用多选结构;

尽量避免多选结构中出现重复匹配,比如:(中国人|中国)

分组及反向引用

分组:使用括号(...)来分组,这样的括号交捕获型括号;

反向引用:就是把捕获分组匹配出来的文本重复使用;格式\1、\2等,有的软件不支持\1、\2,但是一般支持$1、$2这样的格式;

分组的两种可能:顺序分组、嵌套

顺序分组:从左到右按数字排列就好,比如正则表达式(regex1)(regex1)分组后,使用\1会引用regex1捕获的匹配,而\2会引用regex2捕获的匹配;

嵌套:无论如何嵌套,分组的编号都是根据开括号出现的顺序来计数的,规则如下(取自余晟老师的《正则指引》,非商用!):

非捕获型分组:

想分组又不捕获(方便阅读、提高效率),怎么办?用(?:...)来实现;

具有现实意义的例子:公司员工邮箱由名字和邮箱地址组成,格式如下:

yb.l<yb.l@abc-group.com>

现要将他们的名字和邮箱地址分开,用正则是最好的解决方法。有人说,我可以一个一个拷贝,粘贴,这个当然可以,一个两个你可以这样整,一百个,一千个,你得来回折腾多少次?而用正则,两次拷贝、粘贴就搞定。

详见后面的截图。。。

断言(精确匹配)

常见的几种断言:

^:匹配行开头。比如:^[aeiou]\w+表示以字母a、e、i、o、u开头的单词,bag没有被匹配到。


$:匹配行结尾.比如:\w+[aeiou]$表示以字母a、e、i、o、u结尾的单词,只有idea可以被匹配到。


\b:单词边界,

比如:\cat\只能匹配到cat这个单词,包含cat的无法匹配。


环视:四种环视结构,它只匹配位置,不匹配字符,相当于一个条件限制

一个简单的方法就是:把自己想象成被匹配到的字符,然后“你站在那里向右(顺序环视)或者向左(逆序环视)看,是需要满足什么或排除什么”,这里的“什么”是regex匹配的内容。

1.顺序肯定环视(?=regex):意思是从左向右“看”,后面需要出现满足括号内正则表达式(regex)要求的匹配;

比如下面的例子:

2.顺序否定环视(?!regex):意思是从左向右“看”,后面不能出现括号内正则表达式(regex)要求的匹配;

如下面的例子

3.逆向肯定环视(?<=regex):意思是从右向左“看”,前面需要出现满足括号内正则表达式(regex)要求的匹配;

比如下面的例子:

4.逆向否定环视(?<!regex):意思是从右向左“看”,前面不能出现满足括号内正则表达式(regex)要求的匹配;

回溯及正则应用原理(重点和难点)

原理举例:

文本:hot tonic tonight

正则:to(nite|knight|night)

首先,把正则中的每一个字符引擎想象成一个放大镜。然后是用这个放大镜去比对待匹配文本的字符。

然后,从最左边开始,正则引擎t无法匹配文本中的h,引擎在文本中继续前进,来到文本中的字母o,不匹配。继续到文本中的字母t,匹配。然后正则引擎来到o,它无法跟文本中hot的t(前面已经被匹配)后面的空格完成匹配。

显然,本轮匹配失败。

再来,这次轮到tonite引擎了。如上面的过程,toni匹配后,正则引擎的t无法匹配文本的c,匹配失败。

。。。

如此反复,正则引擎的所有选项会尝试去逐一匹配文本,直到正则引擎tonight完全匹配到文本的tonight,匹配成功!

其实,正则表达式是靠正则引擎驱动的,而正则引擎可以分为如下几类:

传统型NFA引擎:功能强大,支持回溯和反向引用;

POSIXNFA引擎:符合标准;

DFA引擎:不一定符合POSIX,速度快,没有回溯和反向引用功能。

NFA和DFA的比较:

1.DFA不支持忽略优先量词(懒惰量词),NFA则支持;

2.DFA不支持捕获型括号、反向引用和回溯,NFA则支持;(NFA最重要的部分:回溯<backtracking>)

3.DFA是文本主导的(text-directed),而NFA是正则主导的(regex directed);4.DFA匹配速度比NFA要快。

一般地,我们使用的软件绝大多数支持传统型NFA,回溯和反向引用的功能非常吸引人。

NFA引擎的测试:

1.被匹配字符:nfa not

2.正则引擎(正则表达式):nfa|nfa not

3.如果仅能匹配到nfa,就是传统型NFA;

4.如果匹配到nfanot,就是POSIXNFA或者DFA。

我们这里只关注传统型NFA。

NFA引擎最重要的性质:

1.它会依次处理各个子表达式或组成元素;

2.遇到需要在两个可能成功的可能中进行选择的时候,它会选择其一,同时记住另一个,以备稍后可能的需要;

3.需要做出选择的情形:量词(决定是否尝试另一次匹配)、多选结构(决定选择哪个多选分支,留下哪个稍后尝试);

回溯的两个要点:

1.如果需要在“进行尝试”和“跳过尝试”之间选择:对于匹配优先量词(贪婪量词),引擎会优先选择“进行尝试”,而对于忽略优先量词(懒惰量词),会选择“跳过尝试”。

2.LIFO(后进先出)原则。

所谓回溯,就是在匹配的位置,正则引擎为了满足其他匹配而不得不进行的字符释放,顺序是从右往左回退,所以叫“回溯”,我叫它“回吐”,把前面“吃到的”字符“吐”一部分出来。

下面用这张图(取自《精通正则表达式》,非商用)开始回溯的讲解之旅:

文本:The name  "McDonald’s" is said "makudonarudo" in Japanese

正则表达式:".*"

上面的过程是这样的:

首先匹配到位置A的双引号,然后点(.)可以匹配任意字符,后面的量词(*)告诉点(.)需要尽可能多的匹配,所以它一下子匹配到了末尾的位置B;

此时,正则引擎来到了上面正则表达式中的红色双引号("),它也要被匹配。怎么办,前面的.*已经把正则引擎推到了位置B,现在为了匹配红色双引号,需要从位置B往后(左)退,一直退到上图中带有红色圈的双引号位置,整个匹配成功。如下图:

这时有人问了:我只想匹配双引号内的字符或字符串,怎么办?

答:使用忽略优先量词(又叫懒惰匹配)或者排除型的优先匹配(又叫贪婪匹配)。

同样的例子,如下,注意正则表达式的写法。

懒惰匹配过程:

Step1 首先匹配".*?"中最左边的双引号;

Step2 然后匹配.*?,因为是懒惰匹配,它直接跳过;

Step3引擎的控制权交给后面的红色双引号"。而此时文本中引擎的位置还停留在第一个双引号后面的字母M的位置,显然,M和正则引擎后面的红色双引号无法匹配,怎么办?

Step4 此时正则引擎控制权交还给点.,而点.可以匹配字母M,然后选择,因为是懒惰匹配*?,又跳过,来到红色的双引号位置,此时又无法匹配,于是重复以上步骤,直到双引号内的内容被全部匹配完成;

Step5 整个过程,引擎的控制权在来回交替。

例外一种方法:排除型的优先匹配

其他使用环视来匹配的例子:

...<B>Billionsand <B>Zillions</B>of suns…, 这里<B>Zillions</B>为期望匹配内容。

下面的方法显然无法实现:

怎么办?可以尝试环视。

具体的操作如下,需要仔细琢磨才能理解。

工作中和excel联手的几个常见应用

1.分离邮箱地址中的人名和地址,然后在单独拷贝到excel中,第一列为人名,第二列就是邮箱地址了。

提取人名(图2.因为窗口大小限制,人名没有完全显示,后同):

邮箱地址一次性提取如下:

不管多少人名,邮箱,两次拷贝、粘贴搞定!

数据提取、合并

提取的例子:黄色部分是从第3列分离出来的。

正则参考如下:

并的例子:

写在最后:

正则,一个高效工具,用电脑的人都应该学学;同时记住:实现同一个匹配,正则的写法不止一种;

再次推荐:《精通正则表达式》。

祝好!

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

推荐阅读更多精彩内容

  • 构建扫描器程序的两个重要方法 boolean hitEnd() 返回true,说明结尾有更多的字符可能会改变本次的...
    mxl0814阅读 572评论 0 1
  • 本文译自 制作正则引擎的作者 Jan Goyvaerts 为工具 RegexBuddy 写的教程版权归原作者所有注...
    极客圈阅读 3,280评论 0 25
  • 匹配基础 对于正则表达式,有两条普适原则: 优先选择最左端的匹配结果; 标准的匹配量词(*、+、?和{min, m...
    戴小白阅读 4,155评论 1 6
  • 自我感觉量词是正则表达式里最不容易理解的地方,所以特别为它做了个总结。 为了容易理解,会简单地结合正则表达式引擎的...
    Happioo阅读 1,780评论 0 4
  • 文/小叶 前言 蒙蒙淅淅,忘携当年,江南雅典—一把油纸伞。青砖上,来往千年,惊动旧主声音,清脆的很。小巷此行略窄了...
    博土阅读 458评论 2 0