首页 > 代码库 > 正则表达式小结

正则表达式小结

概念:正则表达式是记录文本规则的代码,主要是应用在处理大量的数据和文本,而且一定是自动化程度比较高的如检索邮件日志网页信息等等。

分类:搜索和匹配的两种作用构成了模式匹配。搜索,即在字符串任意部分中查找匹配的模式,而匹配是指,判断一个字符串能否从起始处全部或部分的匹配某个模式。搜索通过 search()函数或方法来实现,而匹配是以调用 match()函数或方法实现的。 正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合子组匹配模式重复次数

具体方法如下:

1、 用管道符号( | )匹配多个正则表达式模式,可以匹配不止一个字符串了!

2、从字符串的开头或结尾或单词边界开始匹配( ^/$ /\b /\B )

3、 matching”是试图从整个字符串的开头进行匹配,而searching则可从一个字符串的任意位置开始匹配。

4、 创建字符类( [ ] )。尽管点号可用来匹配任意字符,但有时候你需要匹配某些个特殊的字符。

5、从字符串的开头或结尾或单词边界开始匹配( ^/$ /\b /\B )。匹配的是字符串!

6、指定范围 ( - ) 否定( ^ )和使用闭包操作符 ( *, +, ?, {} ) 实现多次出现/重复匹配。(重点来的!)加号(+)操作符匹配它左边那个正则表达式模式至少出现一次的情况(它也被称为正闭包操作符),而 问号操作符( ? )匹配它左边那个正则表达式模式出现零次或一次的情况。星号或称星号操作符匹配它左边那个正则表达式出现零次或零次以上的情况。

7、 </?[^>]+>   匹配所有合法(和无效的)HTML 标签的字符串???我们注意到问号出现了不只一次(被重载),问号有两种含义:1.单独使用时表示匹配出现零次或一次的情况,2.紧跟在表示重复的元字符后面时,表示要求搜索引擎匹配的字符串越短越好。例如:(+?) 

8、search() 查找字符串中模式首次出现的位置,而不是尝试(在起始处)匹配。

9、正则表达式中最常见的情况包括特殊字符的使用,正则表达式模式的重复出现,以及使用圆括号对匹配模式的各部分进行分组和提取操作。

10、精确查找的某个单词的话就需要\bhi\b精确定位,如果要找hi后面不远处的一个单词lucky的话就要用\bhi\b.* \blucky\b:就可以了!.*连在一起就意味着任意数量的不包含换行的字符。现在\bhi\b.*\bLucy\b的意思就很明显了:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词

 11、是另一个元字符,匹配除了换行符以外的任意字符。*同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配。这里主要是如何分类的,要熟悉正则表达式就要注意符号所代表的属性。

12、空白符,包括空格,制表符(Tab),换行符,中文全角空格.

13、[.?!]匹配标点符号(.?!)不需要转义!

参考地址:http://deerchao.net/tutorials/regex/regex.htm#howtouse

 

 

 

30分钟入门教程:

1.       元字符:(./\w/\s\d:字符)(/^/$/\b:位置)(*/+/?

2.       转义\

3.       重复(*/+/{n,}/{n}/{n,m}

4.       字符类:[]例子:\(?0\d{2}[) -]?\d{8}、[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.?!)[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w。

5.       分支条件:使用分枝条件时,要注意各个条件的顺序。匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了!

栗子:0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(010-12345678),一种是4位区号,7位本地号(0376-2233445)

6.       分组:栗子重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了。栗子如下:

((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][^dfghj]:不包括里面的任意一个!<a[^>]+>匹配用尖括号括起来的以a开头的字符串。\B 只匹配出现在一个单词中间的模式(即,不在单词边界上的字符)。

8.       后向应用:使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成‘也行:(?‘Word‘\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b。

9.       捕获:(exp)(?<name>exp)(?:exp

10.  零宽断言:(?=exp匹配exp前面的位置\b\w+(?=ing\b),匹配ing结尾的单词的前面部分(除了ing以外的部分)

11、(?<=exp匹配exp后面的位置,断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配re开头的单词的后半部分(除了re以外的部分) (?<=\s)\d+(?=\s)匹配以空白符间隔的数字。;?!exp匹配后面跟的不是exp的位置;?<!exp匹配前面不是exp的位置。

重点:负向零宽断言

前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母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>),这个表达式最能表现零宽断言的真正用途。

一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容。(?<=<(\w+)>)指定了这样的前缀被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容(再次提醒,不包括前缀和后缀本身)。

  1. 注释:小括号的另一种用途是通过语法(?#comment)来包含注释。
  2. 贪婪与懒惰:

栗子:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。栗子: .*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)ab(第四到第五个字符)。Notics: 为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权.一句话懒惰限定符就是尽少量地有重复!

Flags:IgnoreCase(忽略大小写)、Multiline(多行模式$^,此时是行开头或是结尾!)、Singleline(单行模式)、IgnorePatternWhitespace(忽略空白)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

l  正则表达式是记录文本规则的代码,主要是应用在处理大量的数据和文本,而且一定是自动化程度比较高的如检索邮件日志网页信息等等。

l  搜索和匹配的两种作用构成了模式匹配。搜索,即在字符串任意部分中查找匹配的模式,而匹配是指,判断一个字符串能否从起始处全部或部分的匹配某个模式。搜索通过 search()函数或方法来实现,而匹配是以调用 match()函数或方法实现的。

l  正则表达式的强大之处在于特殊符号的应用,特殊符号定义了字符集合子组匹配模式重复次数

l  用管道符号( | )匹配多个正则表达式模式,可以匹配不止一个字符串了!

l  从字符串的开头或结尾或单词边界开始匹配( ^/$ /\b /\B )

l  matching”是试图从整个字符串的开头进行匹配,而searching则可从一个字符串的任意位置开始匹配。

l  创建字符类( [ ] )。尽管点号可用来匹配任意字符,但有时候你需要匹配某些个特殊的字符

l  字符串的开头或结尾或单词边界开始匹配( ^/$ /\b /\B )。匹配的是字符串!

l  指定范围 ( - ) 否定( ^ )和使用闭包操作符 ( *, +, ?, {} ) 实现多次出现/重复匹配。(重点来的!)加号(+)操作符匹配它左边那个正则表达式模式至少出现一次的情况(它也被称为正闭包操作符),而

l  问号操作符( ? )匹配它左边那个正则表达式模式出现零次或一次的情况。星号或称星号操作符匹配它左边那个正则表达式出现零次或零次以上的情况。

l  </?[^>]+>   匹配所有合法(和无效的)HTML 标签的字符串???我们注意到问号出现了不只一次(被重载),问号有两种含义:1.单独使用时表示匹配出现零次或一次的情况,2.紧跟在表示重复的元字符后面时,表示要求搜索引擎匹配的字符串越短越好。例如:(+?) 

l  search() 查找字符串中模式首次出现的位置,而不是尝试(在起始处)匹配。

l  正则表达式中最常见的情况包括特殊字符的使用,正则表达式模式的重复出现,以及使用圆括号对匹配模式的各部分进行分组和提取操作。

l  精确查找的某个单词的话就需要\bhi\b精确定位,如果要找hi后面不远处的一个单词lucky的话就要用\bhi\b.* \blucky\b:就可以了!.*连在一起就意味着任意数量的不包含换行的字符。现在\bhi\b.*\bLucy\b的意思就很明显了:先是一个单词hi,然后是任意个任意字符(但不能是换行),最后是Lucy这个单词

l  .是另一个元字符,匹配除了换行符以外的任意字符*同样是元字符,不过它代表的不是字符,也不是位置,而是数量——它指定*前边的内容可以连续重复使用任意次以使整个表达式得到匹配。这里主要是如何分类的,要熟悉正则表达式就要注意符号所代表的属性。

l  空白符,包括空格,制表符(Tab),换行符,中文全角空格.

l  http://deerchao.net/tutorials/regex/regex.htm#howtouse

l  [.?!]匹配标点符号(.?!)不需要转义!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

30分钟入门教程:

1.       元字符:(./\w/\s\d:字符)(/^/$/\b:位置)(*/+/?

2.       转义\

3.       重复(*/+/{n,}/{n}/{n,m}

4.       字符类:[]例子:\(?0\d{2}[) -]?\d{8}[aeiou]就匹配任何一个英文元音字母[.?!]匹配标点符号(.?!)[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w

5.       分支条件:使用分枝条件时,要注意各个条件的顺序。匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了!

栗子:0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(010-12345678),一种是4位区号,7位本地号(0376-2233445)

6.       分组:栗子重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了。栗子如下:

((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][^dfghj]:不包括里面的任意一个!<a[^>]+>匹配用尖括号括起来的以a开头的字符串\B 只匹配出现在一个单词中间的模式(即,不在单词边界上的字符)

8.       后向应用:使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?<Word>\w+)(或者把尖括号换成也行:(?‘Word‘\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k<Word>,所以上一个例子也可以写成这样:\b(?<Word>\w+)\b\s+\k<Word>\b

9.       捕获:(exp)(?<name>exp)(?:exp

10.  零宽断言:(?=exp匹配exp前面的位置\b\w+(?=ing\b),匹配ing结尾的单词的前面部分(除了ing以外的部分)

(?<=exp匹配exp后面的位置,断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配re开头的单词的后半部分(除了re以外的部分) (?<=\s)\d+(?=\s)匹配以空白符间隔的数字。;?!exp匹配后面跟的不是exp的位置;?<!exp匹配前面不是exp的位置。

11.重点:负向零宽断言

前面我们提到过怎么查找不是某个字符或不在某个字符类里的字符的方法(反义)。但是如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?例如,如果我们想查找这样的单词--它里面出现了字母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>),这个表达式最能表现零宽断言的真正用途。

一个更复杂的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含属性的简单HTML标签内里的内容(?<=<(\w+)>)指定了这样的前缀被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。注意后缀里的\/,它用到了前面提过的字符转义;\1则是一个反向引用,引用的正是捕获的第一组,前面的(\w+)匹配的内容,这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b></b>之间的内容(再次提醒,不包括前缀和后缀本身)

1.            注释:小括号的另一种用途是通过语法(?#comment)来包含注释。

2.            贪婪与懒惰:

栗子:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。栗子: .*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)ab(第四到第五个字符)Notics:为什么第一个匹配是aab(第一到第三个字符)而不是ab(第二到第三个字符)?简单地说,因为正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高:最先开始的匹配拥有最高的优先权.一句话懒惰限定符就是尽少量地有重复!

FlagsIgnoreCase(忽略大小写)Multiline(多行模式$^,此时是行开头或是结尾!)、Singleline(单行模式)、IgnorePatternWhitespace(忽略空白)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

正则表达式小结