正则表达式详解

非盈利无广告开发者专用网址导航:www.dev666.com程序员

几个正则表达式编辑器正则表达式

正则表达式是一种查找以及字符串替换操做。正则表达式在文本编辑器中普遍使用,好比正则表达式被用于:编程

  • 检查文本中是否含有指定的特征词
  • 找出文中匹配特征词的位置
  • 从文本中提取信息,好比:字符串的子串
  • 修改文本

与文本编辑器类似,几乎全部的高级编程语言都支持正则表达式。在这样的语境下,“文本”也就是一个字符串,能够执行的操做都是相似的。一些编程语言(好比Perl,JavaScript)会检查正则表达式的语法。微信

正则表达式是什么?

正则表达式只是一个字符串。没有长度限制,可是,这样的正则表达式长度每每较短。以下所示是一些正则表达式的例子:编程语言

  • I had a \S+ day today
  • [A-Za-z0-9\-_]{3,16}
  • \d\d\d\d-\d\d-\d\d
  • v(\d+)(\.\d+)*
  • TotalMessages="(.*?)"
  • <[^<>]>

这些字符串实际上都是微型计算机程序。正则表达式的语法,其实是一种轻量级、简洁、适用于特定领域的编程语言。记住这一点,那么你就很容易理解下面的事情:编辑器

  • 每个正则表达式,均可以分解为一个指令序列,好比“先找到这样的字符,再找到那样的字符,再从中找到一个字符。。。”
  • 每个正则表达式都有输入(文本)和输出(匹配规则的输出,有时是修改后的文本)
  • 正则表达式有可能出现语法错误——不是全部的字符串都是正则表达式
  • 正则表达式语法颇有个性,也能够说很恐怖
  • 有时能够经过编译,使得正则表达式执行更快

在实现中,正则表达式还有其余的特色。本文将重点讨论正则表达式的核心语法,在几乎全部的正则表达式中均可以见到这些规则。函数

特别提示:正则表达式与文件通配语法无关,好比 *.xml学习

正则表达式的基础语法

字符 

正则表达式中包含了一系列的字符,这些字符只能匹配它们自己。有一些被称为“元字符”的特殊字符,能够匹配一些特殊规则。网站

以下所示的例子中,我用红色标出了元字符。ui

  • I had a \S+ day today
  • [A-Za-z0-9\-_]{3,16}
  • \d\d\d\d-\d\d-\d\d
  • v(\d+)(\.\d+)*
  • TotalMessages="(.*?)"
  • <[^<>]*> 

大部分的字符,包括全部的字母和数字字符,是普通字符。也就意味着,它们只能匹配它们本身,以下所示的正则表达式:

cat

意味着,只能匹配一个字符串,以“c”开头,而后是字符“a”,紧跟着是字符“t”的字符串。

到目前为止,正则表达式的功能相似于

  • 常规的Find功能
  • Java中的 String.indexOf() 函数
  • PHP中的 strpos()函数
  • 等等

注意:不作特殊说明,正则表达式中是区分大小写的。可是,几乎全部正则表达式的实现,都会提供一个Flag用来控制是否区分大小写。

 

点“.”

咱们第一个要讲解的元字符是“.”。这个符号意味着能够匹配任意一个字符。以下所示的正则表达式:

c.t

意味着匹配“以c开头,以后是任意一个字符,紧跟着是字母t”的字符串。

在一段文本中,这样的正则表达式能够用来找出catcotczt这样的字符串,甚至能够找出c.t这样的组合,可是不能找到ct或者是coot这样的字符串。

使用反斜杠“\”能够忽略元字符,使得元字符的功能与普通字符同样。因此,正则表达式

c\.t

表示“找到字母c,而后是一个句号(“.”),紧跟着字母t”

反斜杠自己也是一个元字符,这意味着反斜杠自己也能够经过类似的方法变回到普通字符的用途。所以,正则表达式

c\\t

表示匹配“以字符c开头,而后是一个反斜杠,紧跟着是字母t”的字符串。

注意!在正则表达式的实现中,.是不能用于匹配换行符的。”换行符“的表示方法在不一样实现中也不一样。实际编程时,请参考相关文档。在本文中,我认为.是能够匹配任意字符的。实现环境一般会提供一个Flag标志位,来控制这一点。

字符类

字符类是一组在方括号内的字符,表示能够匹配其中的任何一个字符。

  • 正则表达式c[aeiou]t,表示能够匹配的字符串是”以c开头,接着是aeiou中的任何一个字符,最后以t结尾”。在文本的实际应用中,这样的正则表达式能够匹配:cat,cet,cit,cot,cut五种字符串。
  • 正则表达式[0123456789]表示匹配任意一个整数。
  • 正则表达式[a]表示匹配单字符a。

包含忽略字符的例子

  • a表示匹配字符串[a]
  • [\[\]\ab]表示匹配的字符为”[“或者”]”或者”a”,或者”b”
  • [\\\[\]]表示匹配的字符为”\”或者 “[”或者”]”

 

在字符类中,字符的重复和出现顺序并不重要。[dabaaabcc]与[abc]是相同的

重要提示:字符类中和字符类外的规则有时不一样,一些字符在字符类中是元字符,在字符类外是普通字符。一些字符正好相反。还有一些字符在字符类中和字符类外都是元字符,这要视状况而定!

好比,.表示匹配任意一个字符,而[.]表示匹配一个全角句号。这不是一回事!

 

字符类的范围

在字符集中,你能够经过使用短横线来表示匹配字母或数字的范围。

  • [b-f]与[b,c,d,e,f]相同,都是匹配一个字符”b”或”c”或”d”或”e”或”f”
  • [A-Z]与[ABCDEFGHIJKLMNOPQRSTUVWXYZ]相同,都是匹配任意一个大写字母。
  • [1-9]与[123456789]相同,都是匹配任意一个非零数字。

练习

使用目前咱们已经讲解的正则表达式相关知识,在字典中匹配找到含有最多连续元音的单词,同时找到含有最多连续辅音的单词。

答案

[aeiou][aeiou][aeiou][aeiou][aeiou][aeiou] 这样的正则表达式,能够匹配连续含有六个元音的单词,好比 euouae 和 euouaes

一样的,恐怖的正则表达式[bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz] 能够找到连续含有十个辅音的单词sulphhydryls

下文中,咱们会讲解,怎样有效缩短这样的正则表达式长度。

在字符类以外,短横线没有特殊含义。正则表达式a-z,表示匹配字符串“以a开头,而后是一个短横线,以z结尾”。

范围和单独的字符可能在一个字符类中同时出现:

  • [0-9.,]代表匹配一个数字,或者一个全角句号,或者一个逗号
  • [0-9a-fA-F]意味着匹配一个十六进制数
  • [a-zA-Z0-9\-]意味着匹配一个字母、数字或者一个短横线

练习

使用已经介绍过的正则表达式知识,匹配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之间的数。

字符类的反义

你能够在字符类的起始位放一个反义符。

  • [^a]表示匹配任何不是“a”的字符
  • [^a-zA-Z0-9]表示匹配任何不是字母也不是数字的字符
  • [\^abc]匹配一个为“^”或者a或者b或者c的字符
  • [^\^]表示匹配任何不为“^”的字符

练习

在字典中,找到一个不知足“在e以前有i,可是没有c”的例子。

答案

cie和[^c]ei都要能够找到不少这样的例子,好比ancient,science,viel,weigh

 

转义字符类

\d这个正则表达式与[0-9]做用相同,都是匹配任何一个数字。(要匹配\d,应该使用正则表达式\\d)

\w与[0-9A-Za-z]相同,都表示匹配一个数字或字母字符

\s意味着匹配一个空字符(空格,制表符,回车或者换行)

另外

  • \D与[^0-9]相同,表示匹配一个非数字字符。
  • \W与[^0-9A-Za-z]相同,表示匹配一个非数字同时不是字母的字符。
  • \S表示匹配一个非空字符。

这些是你必须掌握的字符。你可能已经注意到了,一个全角句号“.”也是一个字符类,能够匹配任意一个字符。

不少正则表达式的实现中,提供了更多的字符类,或者是标志位在ASCII码的基础上,扩展示有的字符类。

特别提示:统一字符集中包含除了0至9以外的更多数字字符,一样的,也包含更多的空字符和字母字符。实际使用正则表达式时,请仔细查看相关文档。

练习

简化正则表达式 [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9].

答案

\d\d\d\d-\d\d-\d\d.

 

重复

在字符或字符集以后,你可使用{ }大括号来表示重复

  • 正则表达式a{1}与a意思相同,都表示匹配字母a
  • a{3}表示匹配字符串“aaa”
  • a{0}表示匹配空字符串。从这个正则表达式自己来看,它毫无心义。若是你对任何文本执行这样的正则表达式,你能够定位到搜索的起始位置,即便文本为空。
  • a\{2\}表示匹配字符串“a{2}”
  • 在字符类中,大括号没有特殊含义。[{}]表示匹配一个左边的大括号,或者一个右边的大括号

练习

简化下面的正则表达式

  • z.......z
  • \d\d\d\d-\d\d-\d\d
  • [aeiou][aeiou][aeiou][aeiou][aeiou][aeiou]
  • [bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz][bcdfghjklmnpqrstvwxyz]

答案

  • z.{7}z
  • \d{4}-\d{2}-\d{2}
  • [aeiou]{6}
  • [bcdfghjklmnpqrstvwxyz]{10}

注意:重复字符是没有记忆性的,好比[abc]{2}表示先匹配”a或者b或者c”,再匹配”a或者b或者c”,与匹配”aa或者ab或者ac或者ba或者bb或者bc或者ca或者cb或者cc“同样。[abc]{2}并不能表示匹配”aa或者bb或者cc“

 

指定重复次数范围

重复次数是能够指定范围的

  • x{4,4}与x{4}相同
  • colou{0,1}r表示匹配colour或者color
  • a{3,5}表示匹配aaaaa或者aaaa或者aaa

注意这样的正则表达式会优先匹配最长字符串,好比输入 I had an aaaaawful day会匹配单词aaaaawful中的aaaaa,而不会匹配其中的aaa。

重复次数是能够有范围的,可是有时候这样的方法也不能找到最佳答案。若是你的输入文本是I had an aaawful daaaaay那么在第一次匹配时,只能找到aaawful,只有再次执行匹配时才能找到daaaaay中的aaaaa.

重复次数的范围能够是开区间

  • a{1,}表示匹配一个或一个以上的连续字符a。依然是匹配最长字符串。当找到第一个a以后,正则表达式会尝试匹配尽可能多个的连续字母a。
  • .{0,}表示匹配任意内容。不管你输入的文本是什么,即便是一个空字符串,这个正则表达式都会成功匹配全文并返回结果。

练习

使用正则表达式找到双引号。要求输入字符串可能包含任意个字符。

调整你的正则表达式使得在一对双引号中间再也不包含其余的双引号。

答案

 ".{0,}", 而后 "[^"]{0,}".

 

关于重复的转义字符

?与{0,1}相同,好比,colou?r表示匹配colour或者color

*与{0,}相同。好比,.*表示匹配任意内容

+与{1,}相同。好比,\w+表示匹配一个词。其中”一个词”表示由一个或一个以上的字符组成的字符串,好比_var或者AccountName1.

这些是你必须知道的经常使用转义字符,除此以外还有:

  • \?\*\+ 表示匹配字符串”?*+”
  • [?*+]表示匹配一个问号,或者一个*号,或者一个加号

练习

简化下列的正则表达式:

  • ".{0,}" and "[^"]{0,}"
  • x?x?x?
  • y*y*
  • z+z+z+z+

答案

  • ".*" and "[^"]*"
  • x{0,3}
  • y*
  • z{4,}

 

练习

写出正则表达式,寻找由非字母字符分隔的两个单词。若是是三个呢?六个呢?

\w+\W+\w+\w+\W+\w+\W+\w+\w+\W+\w+\W+\w+\W+\w+\W+\w+\W+\w+.

下文中,咱们将简化这个正则表达式。

 

 非贪婪匹配

正则表达式 “.*” 表示匹配双引号,以后是任意内容,以后再匹配一个双引号。注意,其中匹配任意内容也能够是双引号。一般状况下,这并非颇有用。经过在句尾加上一个问号,可使得字符串重复再也不匹配最长字符。

  • \d{4,5}?表示匹配\d\d\d\d或者\d\d\d\d\d。也就是和\d{4}同样
  • colou??r与colou{0,1}r相同,表示找到color或者colour。这与colou?r同样。
  • “.*?”表示先匹配一个双引号,而后匹配最少的字符,而后是一个双引号,与上面两个例子不一样,这颇有用。

选择匹配

你可使用|来分隔能够匹配的不一样选择:

  • cat|dog表示匹配”cat”或者”dog”
  • red|blue|以及red||blue以及|red|blue都表示匹配red或者blue或者一个空字符串
  • a|b|c与[abc]相同
  • cat|dog|\|表示匹配”cat”或者”dog”或者一个分隔符”|“
  • [cat|dog]表示匹配a或者c或者d或者g或者o或者t或者一个分隔符“|”

练习

简化下列正则表达式:

  • s|t|u|v|w
  • aa|ab|ba|bb
  • [abc]|[^abc]
  • [^ab]|[^bc]
  • [ab][ab][ab]?[ab]?

答案

  • [s-w]
  • [ab]{2}
  • .
  • [^b]
  • [ab]{2,4}

练习

使用正则表达式匹配1到31之间的整数,[1-31]不是正确答案!

这样的正则表达式不惟一. [1-9]|[12][0-9]|3[01] 是其中之一。

 

分组

你可使用括号表示分组:

  • 经过使用 Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day 匹配一周中的某一天
  • (\w*)ility  与 \w*ility 相同。都是匹配一个由”ility”结尾的单词。稍后咱们会讲解,为什么第一种方法更加有用。
  • [()]表示匹配任意一个左括号或者一个右括号

 

分组能够包括空字符串:

  • (red|blue)表示匹配red或者blue或者是一个空字符串
  • abc()def与abcdef相同

你也能够在分组的基础上使用重复:

  • (red|blue)?与(red|blue|)相同
  • \w+(\s+\w+)表示匹配一个或多个由空格分隔的单词

练习

简化正则表达式 \w+\W+\w+\W+\w+ 以及 \w+\W+\w+\W+\w+\W+\w+\W+\w+\W+\w+.

答案

\w+(\W+\w+){2}\w+(\W+\w+){5}.

 

单词分隔符

在单词和非单词之间有单词分隔符。记住,一个单词\w是[0-9A-Za-z_],而非单词字符是\W(大写),表示[^0-9A-Za-z_].

在文本的开头和结尾一般也有单词分隔符。

在输入文本it’s a cat中,实际有八个单词分隔符。若是咱们在cat以后在上一个空格,那就有九个单词分隔符。.

  • \b表示匹配一个单词分隔符
  • \b\w\w\w\b表示匹配一个三字母单词
  • a\ba表示匹配两个a中间有一个单词分隔符。这个正则表达式永远不会有匹配的字符,不管输入怎样的文本。

单词分隔符自己并非字符。它们的宽度为0。下列正则表达式的做用不一样

  • (\bcat)\b
  • (\bcat\b)
  • \b(cat)\b
  • \b(cat\b)

练习

在词典中找到最长的单词。

答案

在尝试以后发现,\b.{45,}\b能够在字典中找到最长单词

 

换行符

一篇文本中能够有一行或多行,行与行之间由换行符分隔,好比:

  • Line一行文字
  • Line break换行符
  • Line一行文字
  • Line break换行符
  • Line break换行符
  • Line一行文字

注意,全部的文本都是以一行结束的,而不是以换行符结束。可是,任意一行均可能为空,包括最后一行。

行的起始位置,是在换行符和下一行首字符之间的空间。考虑到单词分隔符,文本的起始位置也能够当作是首行位置。

最后一行是最后一行的尾字符和换行符之间的空间。考虑到单词分隔符,文本的结束也能够认为是行的结束。

那么新的格式表示以下:

  • Start-of-line, line, end-of-line
  • Line break
  • Start-of-line, line, end-of-line
  • Line break
  • Line break
  • Start-of-line, line, end-of-line

基于上述概念:

  • ^表示匹配行的开始位置
  • $表示匹配行的结束位置
  • ^&表示一个空行
  • ^.*& 表示匹配全文内容,由于行的开始符号也是一个字符,"."会匹配这个符号。找到单独的一行,可使用 ^.*?$
  • \^\$表示匹配字符串“^$”
  • [$]表示匹配一个$。可是,[^]不是合法的正则表达式。记住在方括号中,字符有不一样的特殊含义。要想在方括号内匹配^,必须用[\^]

与字符分隔符同样,换行符也不是字符。它们宽度为0.以下所示的正则表达式做用不一样:

  • (^cat)$
  • (^cat$)
  • ^(cat)$
  • ^(cat$)

练习

使用正则表达式在《时间机器》中找到最长的一行。

答案

使用正则表达式^.{73,}$能够匹配长度为73的一行

 

文本分界

在不少的正则表达式实现中,将^和$做为文本的开始符号和结束符号。

还有一些实现中,用\A和\z做为文本的开始和结束符号。

 

捕捉和替换

从这里开始,正则表达式真正体现出了它的强大。

捕获组

你已经知道了使用括号能够匹配一组符号。使用括号也能够捕获子串。假设正则表达式是一个小型计算机程序,那么捕获子串就是它输出的一部分。

正则表达式(\w*)ility表示匹配以ility结尾的词。第一个被捕获的部分是由\w*控制的。好比,输入的文本内容中有单词accessibility,那么首先被捕获的部分是accessib。若是输入的文本中有单独的ility,则首先被捕获的是一个空字符串。

你可能会有不少的捕获字符串,它们可能靠得很近。捕获组从左向右编号。也就是只须要对左括号计数。

假设有这样的正则表达式:(\w+) had a ((\w+) \w+)

输入的内容是:I had a nice day 

  • 捕获组1:I
  • 捕获组2:nice day
  • 捕获组3:nice

在一些正则表达式的实现中,你能够从零开始编号,编号零表示匹配整句话:I had a nice day.

在其余的实现中,若是没有制定捕获组,那么捕获组1会自动地填入捕获组0的信息。

是的,这也意味着会有不少的括号。有一些正则表达式的实现中,提供了“非捕获组”的语法,可是这样的语法并非标准语法,所以咱们不会介绍。

从一个成功的匹配中返回的捕获组个数,与使用原来的正则表达式得到的捕获组个数相同。记住这一点,你能够解释一些奇怪的现象。.

正则表达式((cat)|dog)表示匹配cat或者dog。这里有两个捕获组,若是输入文本是dog,那么捕获组1是dog,捕获组2为空。

正则表达式a(\w)*表示匹配一个以a开头的单词。这里只有一个捕获组

  • 若是输入文本为a,捕获组1为空。
  • 若是输入文本为ad,捕获组为d
  • 若是输入文本为avocado,捕获组1为v。可是捕获组0表示整个单词avocado.

 

替换

假如你使用了一个正则表达式去匹配字符串,你能够描述另一个字符串来替换其中的匹配字符。用来替换的字符串称为替换表达式。它的功能相似于

  • 常规的Replace会话
  • Java中的String.replace()函数
  • PHP的str_replace()函数
  • 等等

练习

将《时间机器》中全部的元音字母替换为r。

答案

使用正则表达式[aeiou]以及[AEIOU],对应的替换字符串分别为r,R.

可是,你能够在替换表达式中引用捕获组。这是在替换表达式中,你能够惟一操做的地方。这也是很是有效的,由于这样你就不用重构你找到的字符串。

假设你正在尝试将美国风格的日期表示MM/DD/YY替换为ISO 8601日期表示YYYY-MM-DD

  • 从正则表达式(\d\d)/(\d\d)/(\d\d)开始。注意,这其中有三个捕获组:月份,日期和两位的年份。
  • .捕获组的内容和捕获组编号之间用反斜杠分隔,所以你的替换表达式应该是20\3-\1-\2.
  • 若是咱们输入的文本中包含03/04/05表示2005年3月4日那么:
    • 捕获组1:03
    • 捕获组2:04
    • 捕获组3:05
    • 替换字符串2005-03-04.

在替换表达式中,你能够屡次使用捕获组

  • 对于双元音,正则表达式为([aeiou]),替换表达式为\l\l
  • 在替换表达式中不能使用反斜杠。好比,你在计算机程序中但愿使用字符串中使用部分文本。那么,你必须在每一个双引号或者反斜杠以前加上反斜杠。
  • 你的正则表达式能够是([\\”])。捕获组1是双引号或者反斜杠
  • 你的替换表达式应该是\\\l

在某些实现中,采用美圆符号$代替\

练习

使用正则表达式和替换表达式,将23h59这样的时间戳转化为23:59.

答案

正则表达式finds the timestamps, 替换表达式\1:\2

 

反向引用

在一个正则表达式中,你也能够引用捕获组。这称做:反向引用

好比,[abc]{2}表示匹配aa或者ab或者ac或者ba或者bb或者bc或者ca或者cb或者cc.可是{[abc]}\1表示只匹配aa或者bb或者cc.

练习

在字典中,找到包含两次重复子串的最长单词,好比papacoco

\b(.{6,})\1\b 匹配 chiquichiqui.

若是咱们不在意单词的完整性,咱们能够忽略单词的分解,使用正则表达式 (.{7,})\1匹配countercountermeasure 以及 countercountermeasures.

使用正则表达式编程

特别提醒:

过分使用的反斜杠

在一些编程语言,好比Java中,对于包含正则表达式的字符串没有特殊标记。字符串有着本身的过滤规则,这是优先于正则表达式规则的,这是频繁使用反斜杠的缘由。

好比在Java中

  • 匹配一个数字,使用的正则表达式从\d变为代码中的String re= “\\d”
  • 匹配双引号字符串的正则表达式从"[^"]*" 变为String re = “\”[^\”]*\””
  • String re = "\\s"; 和String re = "[ \t\r\n]"; 是等价的. 注意它们实际执行调用时的层次不一样。

在其余的编程语言中,正则表达式是由特殊标明的,好比使用/。下面是JavaScript的例子:

  • 匹配一个数字,\d会简单写成 var regExp = /\d/;.
  • 匹配一个反斜杠或者一个左边的方括号或者一个右边的方括号, var regExp = /[\\\[\]]/;
  • var regExp = /\s/; 和 var regExp = /[ \t\r\n]/; 是等价的
  • 固然,这意味着在使用/时必须重复两次。好比找到URL必须使用var regExp = /https?:\/\//;.

我但愿如今你能明白,我为何让你特别注意反斜杠。

 

动态正则表达式

当你动态建立一个正则表达式的时候请特别当心。若是你使用的字符串不够完善的花,可能会有意想不到的匹配结果。这可能致使语法错误,更糟糕的是,你的正则表达式语法正确,可是结果没法预料。

错误的Java代码:

String sep = System.getProperty(“file.separator”); String[] directories = filePath.split(sep);

Bug:String.split() 认为sep是一个正则表达式。可是,在Windows中,Sep是表示匹配一个反斜杠,也就是与正则表达式”\\”相同。这个正则表达式是正确的,可是会返回一个异常:PatternSyntaxException.

任何好的编程语言都会提供一种良好的机制来跳过字符串中全部的元字符。在Java中,你能够这样实现:

String sep = System.getProperty(“file.separator”);

String[] directories = filePath.split(Pattern.quote(sep));

 

循环中的正则表达式

将正则表达式字符串加入反复运行的程序中,是一种开销很大的操做。若是你能够在循环中避免使用正则表达式,你能够大大提升效率。

 

其余建议

输入验证

正则表达式能够用来进行输入验证。可是严格的输入验证会使得用户体验较差。好比:

信用卡号

在一个网站上,我输入了个人卡号好比 1234 5678 8765 4321 网站拒绝接收。由于它使用了正则表达式\d{16}。

正则表达式应该考虑到用户输入的空格和短横线。

实际上,为何不先过滤掉全部的非数字字符,而后再进行有效性验证呢?这样作,能够先使用\D以及空的替换表达式。

练习

在不先过滤掉全部的非数字字符的状况下,使用正则表达式验证卡号的正确性。

答案

\D*(\d\D*){16} is one of several variations which would accomplish this.

 

名字

不要使用正则表达式来验证姓名。实际上,即便能够,也不要企图验证姓名。

程序员对名字的错误见解:

  • 名字中不含空格
  • 名字中没有链接符号
  • 名字中只会使用ASCII码字符
  • 名字中出现的字都在特殊字符集中
  • 名字至少要有M个字的长度
  • 名字不会超过N个字的长度
  • 人们只有一个名
  • 人们只有一个中间名
  • 人们只有一个姓(最后三条是从英语的人名考虑)

 

电子邮件地址

不要使用正则表达式验证邮箱地址的正确性。

首先,这样的验证很难是精确的。电子邮件地址是能够用正则表达式验证的,可是表达式会很是的长而且复杂。

短的正则表达式会致使错误。(你知道吗?电子邮箱地址中会有一些注释)

第二,即便一个电子邮件地址能够成功匹配正则表达式,也不表明这个邮箱实际存在。邮箱的惟一验证方法,是发送验证邮件。

 

注意

在严格的应用场景中,不要使用正则表达式来解析HTML或者XML。解析HTML或者XML:

  1. 使用简单的正则表达式不能完成
  2. 整体来讲很是困难
  3. 已经有其余的方法解决

找到一个已经有的解析库来完成这个工做

总结

  • 字符: a b c d 1 2 3 4 etc.
  • 字符类: . [abc] [a-z] \d \w \s
    • . 表明任何字符
    • \d 表示“数字”
    • \w   表示”字母”, [0-9A-Za-z_]
    • \s   表示 “空格, 制表符,回车或换行符”
    • 否认字符类: [^abc] \D \W \S
  • 重复: {4} {3,16} {1,} ? * +
    • ? 表示 “零次或一次”
    • * 表示 “大于零次”
    • + 表示 “一次或一次以上”
    • 若是不加上?,全部的重复都是最长匹配的(贪婪)
  • 分组: (Septem|Octo|Novem|Decem)ber
  • 词,行以及文本的分隔: \b ^ $ \A \z
  • 转义字符: \1 \2 \3 etc. (在匹配表达式和替换表达式中均可用)
  • 元字符: . \ [ ] { } ? * + | ( ) ^ $
  • 在字符类中使用元字符: [ ] \ - ^
  • 使用反斜杠能够忽略元字符: \
  • 更多内容与学习交流请关注微信公众帐号:开发者周刊

相关文章
相关标签/搜索