55分钟学会正则表达式
http://blog.jobbole.com/63398/
正则表达式是一种查找以及字符串替换操作。正则表达式在文本编辑器中广泛使用,比如正则表达式被用于:
与文本编辑器相似,几乎所有的高级编程语言都支持正则表达式。在这样的语境下,“文本”也就是一个字符串,可以执行的操作都是类似的。一些编程语言(比如Perl,JavaScript)会检查正则表达式的语法。 正则表达式是什么? 正则表达式只是一个字符串。没有长度限制,但是,这样的正则表达式长度往往较短。如下所示是一些正则表达式的例子:
这些字符串实际上都是微型计算机程序。正则表达式的语法,实际上是一种轻量级、简洁、适用于特定领域的编程语言。记住这一点,那么你就很容易理解下面的事情:
在实现中,正则表达式还有其他的特点。本文将重点讨论正则表达式的核心语法,在几乎所有的正则表达式中都可以见到这些规则。 特别提示:正则表达式与文件通配语法无关,比如 *.xml 正则表达式的基础语法字符正则表达式中包含了一系列的字符,这些字符只能匹配它们本身。有一些被称为“元字符”的特殊字符,可以匹配一些特殊规则。 如下所示的例子中,我用红色标出了元字符。
大部分的字符,包括所有的字母和数字字符,是普通字符。也就意味着,它们只能匹配它们自己,如下所示的正则表达式: cat 意味着,只能匹配一个字符串,以“c”开头,然后是字符“a”,紧跟着是字符“t”的字符串。 到目前为止,正则表达式的功能类似于
注意:不做特殊说明,正则表达式中是区分大小写的。但是,几乎所有正则表达式的实现,都会提供一个Flag用来控制是否区分大小写。
点“.”我们第一个要讲解的元字符是“.”。这个符号意味着可以匹配任意一个字符。如下所示的正则表达式: c.t 意味着匹配“以c开头,之后是任意一个字符,紧跟着是字母t”的字符串。 在一段文本中,这样的正则表达式可以用来找出 使用反斜杠“”可以忽略元字符,使得元字符的功能与普通字符一样。所以,正则表达式 c.t 表示“找到字母c,然后是一个句号(“.”),紧跟着字母t” 反斜杠本身也是一个元字符,这意味着反斜杠本身也可以通过相似的方法变回到普通字符的用途。因此,正则表达式 ct 表示匹配“以字符c开头,然后是一个反斜杠,紧跟着是字母t”的字符串。 注意!在正则表达式的实现中,.是不能用于匹配换行符的。”换行符“的表示方法在不同实现中也不同。实际编程时,请参考相关文档。在本文中,我认为.是可以匹配任意字符的。实现环境通常会提供一个Flag标志位,来控制这一点。 字符类字符类是一组在方括号内的字符,表示可以匹配其中的任何一个字符。
包含忽略字符的例子
在字符类中,字符的重复和出现顺序并不重要。[dabaaabcc]与[abc]是相同的 重要提示:字符类中和字符类外的规则有时不同,一些字符在字符类中是元字符,在字符类外是普通字符。一些字符正好相反。还有一些字符在字符类中和字符类外都是元字符,这要视情况而定! 比如,.表示匹配任意一个字符,而[.]表示匹配一个全角句号。这不是一回事! 字符类的范围在字符集中,你可以通过使用短横线来表示匹配字母或数字的范围。
练习使用目前我们已经讲解的正则表达式相关知识,在字典中匹配找到含有最多连续元音的单词,同时找到含有最多连续辅音的单词。 答案 下文中,我们会讲解,怎样有效缩短这样的正则表达式长度。 在字符类之外,短横线没有特殊含义。正则表达式a-z,表示匹配字符串“以a开头,然后是一个短横线,以z结尾”。 范围和单独的字符可能在一个字符类中同时出现:
练习使用已经介绍过的正则表达式知识,匹配YYYY-MM-DD格式的日期。 [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].同样的,下文中,我们会介绍怎样有效减少这样的正则表达式长度。 虽然你可以尝试在正则表达式中使用一些非字母或数字作为范围的最后一个符号,比如abc[!-/]def,但是这并不是在每种实现中都合法。即使这样的语法是合法的,这样的语义也是模糊的。最好不要这样使用。 同时,你必须谨慎选择范围的边界值。即使[A-z]在你使用的实现中,是合法的,也可能会产生无法预料的运行结果。(注意,在z到a之间,是有字符存在的) 注意:范围的字符值代表的是字符而已,并不能代表数值范围,比如[1-31]表示匹配一个数字,是1或者2或者3,而不是匹配一个数值在1到31之间的数。 字符类的反义你可以在字符类的起始位放一个反义符。
练习在字典中,找到一个不满足“在e之前有i,但是没有c”的例子。 答案cie和[^c]ei都要可以找到很多这样的例子,比如ancient,science,viel,weigh 转义字符类d这个正则表达式与[0-9]作用相同,都是匹配任何一个数字。(要匹配d,应该使用正则表达式d) w与[0-9A-Za-z]相同,都表示匹配一个数字或字母字符 s意味着匹配一个空字符(空格,制表符,回车或者换行) 另外
这些是你必须掌握的字符。你可能已经注意到了,一个全角句号“.”也是一个字符类,可以匹配任意一个字符。 很多正则表达式的实现中,提供了更多的字符类,或者是标志位在ASCII码的基础上,扩展现有的字符类。 特别提示:统一字符集中包含除了0至9之外的更多数字字符,同样的,也包含更多的空字符和字母字符。实际使用正则表达式时,请仔细查看相关文档。 练习 简化正则表达式 答案 重复在字符或字符集之后,你可以使用{ }大括号来表示重复
练习简化下面的正则表达式
答案
注意:重复字符是没有记忆性的,比如[abc]{2}表示先匹配”a或者b或者c”,再匹配”a或者b或者c”,与匹配”aa或者ab或者ac或者ba或者bb或者bc或者ca或者cb或者cc“一样。[abc]{2}并不能表示匹配”aa或者bb或者cc“ 指定重复次数范围重复次数是可以指定范围的
注意这样的正则表达式会优先匹配最长字符串,比如输入 重复次数是可以有范围的,但是有时候这样的方法也不能找到最佳答案。如果你的输入文本是I had an aaawful daaaaay那么在第一次匹配时,只能找到aaawful,只有再次执行匹配时才能找到daaaaay中的aaaaa. 重复次数的范围可以是开区间
练习使用正则表达式找到双引号。要求输入字符串可能包含任意个字符。 调整你的正则表达式使得在一对双引号中间不再包含其他的双引号。 答案 关于重复的转义字符?与{0,1}相同,比如,colou?r表示匹配colour或者color *与{0,}相同。比如,.*表示匹配任意内容 +与{1,}相同。比如,w+表示匹配一个词。其中”一个词”表示由一个或一个以上的字符组成的字符串,比如_var或者AccountName1. 这些是你必须知道的常用转义字符,除此之外还有:
练习简化下列的正则表达式:
答案
练习写出正则表达式,寻找由非字母字符分隔的两个单词。如果是三个呢?六个呢? 下文中,我们将简化这个正则表达式。 非贪婪匹配正则表达式 “.*” 表示匹配双引号,之后是任意内容,之后再匹配一个双引号。注意,其中匹配任意内容也可以是双引号。通常情况下,这并不是很有用。通过在句尾加上一个问号,可以使得字符串重复不再匹配最长字符。
选择匹配你可以使用|来分隔可以匹配的不同选择:
练习简化下列正则表达式:
答案
练习使用正则表达式匹配1到31之间的整数,[1-31]不是正确答案! 这样的正则表达式不唯一. 分组你可以使用括号表示分组:
练习在《时间机器中》找到一对括号中的内容,然后通过修改正则表达式,找到不含括号的内容。
|