之前在《JavaScript权威指南》和《JavaScript高级程序设计》中看到过有关正则表达式的讲解,但是都半知半解,真正到用的时候又是不知道从何开始,很大一部分原因还是自己实践的少,今天看完了《正则表达式必知必会》,觉得讲的挺好,浅显易懂,每种表达都有相应的例子说明,适合初学者学习,现在和大家分享一下:
一、什么是正则表达式?
正则表达式:简单地说,就是一些用来匹配和处理文本的字符串。正则表达式语言并不是一种完备的程序设计语言,甚至算不上是一种能够直接安装并运行的程序。更准确的说,正则表达式语言是内置在其他语言或软件产品里的“迷你”语言。
用途:1.用正则表达式进行搜索;2.用正则表达式进行替换
工具:可以在http://www.forta.com/books/0672325667/的Regular Expression Tester正则表达式测试工具进行测试。
二、基本语法
1、匹配单个字符
(1)匹配纯文本
文本:Today,I will learn javascript.
正则表达式:ava(区分大小写)
匹配结果:Today,I will learn javascript.
(2)修饰符
用以说明高级匹配模式的规则,和之前讨论的正则表达式语法不同,修饰符是放在”/“符号之外的,也就是说,它们不是出现在两条斜线之间,而是第二条斜线之后。
字符
|
含义
|
i
|
执行不匹配大小写的匹配
|
g
|
执行一个全局匹配,简言之,即找到所有的匹配,而不是在找到第一个之后就停止
|
m
|
多行匹配模式,^匹配一行的开头和字符串的开头,$匹配行的结束和字符串的结束
|
(3)匹配任意字符
.英文句号,可以匹配任何一个单个字符,可以是字母、数字甚至是.本身。
文本:cat cot cst c7r
正则表达式:c.t
匹配结果:cat cot cst
注意:
- 在同一个正则表达式里允许使用多个.字符,它们既可以连续出现(一个接着一个——..将匹配任意两个字符),也可以间隔着出现在模式的不同位置。
- 如果想要匹配.字符本身而不是它在正则表达式里的特殊含义,就要在.前面加上一个\(反斜杠)字符来对它进行转义。\是一个元字符,表示这个字符有特殊含义,而不是字符本身含义。在正则表达式里有特殊含义的字符序列总是以\字符开头。
2、匹配一组字符
(1)匹配多个字符中的某一个
上边介绍过.字符可以匹配任意单个字符,我们使用了c.t来匹配cat/cot/cst,但是如果我们只想匹配cat和cot呢怎么办?
在正则表达式里,可以使用元字符[和]来定义一个字符集合。在使用[和]定义的字符集合里,这两个元字符之间的所有字符都是该集合的组成部分。[和]不匹配任何字符,它们只负责定义一个字符集合。
文本:cat cot cst c7r
正则表达式:c[ao]t
匹配结果:cat cot
(2)利用字符区间集合
文本:cat cot cst c7t
正则表达式:c[0123456789]t
匹配结果:c7t
注意:
在使用正则表达式时,会频繁用到一些字符区间(0~9、A~Z等),为了简化字符区间的定义,正则表达式提供了一个特殊的元字符,字符区间可以使用-(连字符)来定义。作为元字符,-只能用在[和]之间,在字符集合以外的地方,-只是一个普通字符,只能与-本身相匹配。
文本:cat cot cst c7t
正则表达式:c[0-9]t **与[0123456789]功能相同**
匹配结果:c7t
再比如:使用正则表达式匹配RGB值
文本:<body bgcolor="#336633" text="#FFFFFF">
正则表达式:#[0-9A-Za-z][0-9A-Za-z][0-9A-Za-z][0-9A-Za-z][0-9A-Za-z][0-9A-Za-z]
匹配结果:<body bgcolor="#336633" text="#FFFFFF">
(3)取非匹配
换句话说,就是除了那个字符集合里的字符,其他字符都可以匹配。
用元字符^来表明你想对一个字符集合进行取非匹配。
文本:cat cot cst c7t
正则表达式:c[^0-9]t
匹配结果:cat cot cst
小结:
元字符[和]用来定义一个字符集合,其含义是必须匹配该集合里的字符之一。定义一个字符集合的具体做法有两种:一是把所有的字符都列举出来;二是利用元字符-以字符区间的方式给出。字符集合可以用元字符^来求非。
3、使用元字符
(1)对特殊字符进行转义
常用的特殊字符,比如元字符,元字符是一些在正则表达式里有着特殊含义的字符,所以这些字符就无法用来代表它们本身。
这时,在元字符前边加上反斜杠就可以对它进行转义:转义序列\.将匹配.本身。
对元字符转义需要用到\字符,这意味着\字符也是一个元字符,它的特殊含义是对其他元字符进行转义,在需要匹配\本身时,使用\\。
(2)匹配空白字符
\r\n匹配一个“回车+换行”组合。
元字符
|
说明
|
[\b]
|
回退(并删除)一个字符(Backspace键)
|
\f
|
换页符
|
\n
|
换行符
|
\r
|
回车符
|
\t
|
制表符(Tab键)
|
\v
|
垂直制表符
|
(3)匹配数字(与非数字)
元字符
|
说明
|
\d
|
任何一个数字字符(等价于[0-9])
|
\D
|
任何一个非数字字符(等价于[^0-9])
|
(4)匹配字母和数字(与非字母和数字)
字母和数字,A到Z(不分大小写)、数字0到9,再加上下划线字符(_)
元字符
|
说明
|
\w
|
任何一个字母数字字符(大小写均可)或下划线字符(等价于[A-Za-z0-9_])
|
\W
|
任何一个非字母数字或非下划线字符(等价于[^A-Za-z0-9_])
|
(5)匹配空白字符(与非空白字符)
元字符
|
说明
|
\s
|
任何一个空白字符(等价于[\f\n\r\t\v])
|
\S
|
任何一个非空白字符(等价于[^\f\n\r\t\v])
|
4、重复匹配
(1)匹配一个或多个字符+
+匹配一个或多个字符(至少一个,不匹配零个字符的情况)
注意:在给一个字符集合加上+后缀的时候,必须把+放在这个字符集合的外面。比如说,[0-9]+是正确的,[0-9+]则不是,但是[0-9+]其实也是一个合法的正则表达式,但他匹配的不是一个或多个数字,它定义了一个由数字0到9和+构成的字符集合,因而只能匹配一个单个的数字字符或加号。、
(2)匹配零个或多个字符*
*匹配0个或多个字符
(3)匹配0个或1个字符?
?只能匹配一个字符的零次或一次出现,最多不超过一次。
文本:The URL is http://www.forta.com/, to connect securely use https://forta.com/ instead.
正则表达式:http?://[\w./]+
匹配结果:The URL is http://www.forta.com/, to connect securely use https://forta.com/ instead.
(4)限定匹配次数
重复次数要用{和}字符来给出,把数值写在他们之间。
注意:{}也是元字符,如果要匹配其本身,应该用\进行转义。
{n}:重复n次
如:[0-5]{2} 0-5之间的数字重复两次,即可以匹配01 02 03 04 05 一直到55 之间的任意数字
{m,n}:重复m到n次,即最少重复m次,最多重复n次
如:\d{1,3} 匹配1个到3个数字字符
{n,+}:至少重复n次
如:\d{3,}至少匹配3个数字字符
(5)防止匹配过度——贪婪型元字符和懒惰型元字符
贪婪型元字符
|
懒惰型元字符
|
*
|
*?
|
+
|
+?
|
{n, }
|
{n,}?
|
文本:This offer is not available to customers living in <B>AK</B> and <B>HI</B>.
正则表达式:<[Bb]>.*</[Bb]>
匹配结果:This offer is not available to customers living in <B>AK</B> and <B>HI</B>.
为什么会这样呢?因为+和*都是所谓的“贪婪型”元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止的,会尽可能地从一段文本的开头一直匹配到这段文本的末尾,而不是从这段文本的开头匹配到碰到第一个匹配时为止。
“懒惰型”在这里的含义是匹配尽可能少的字符。
文本:This offer is not available to customers living in <B>AK</B> and <B>HI</B>.
正则表达式:<[Bb]>.*?</[Bb]>
匹配结果:This offer is not available to customers living in <B>AK</B> and <B>HI</B>.
5、位置匹配
(1)单词边界
\b匹配一个单词的开始和结尾
\B匹配不是单词的字符
(2)字符串边界
^定义字符串的开头,$定义字符串的结尾
注意:之前我们已经见过^表示“非操作”,^是几个有着多种用途的元字符之一,只有当它出现在一个字符集合里(被放在[和]之间)并紧跟在左方括号[的后面时,才能发挥“求非“作用。如果是在一个字符集合的外面并位于一个模式的开头,^将匹配字符串的开头。
(3)分行匹配
(?m)分行匹配模式将使得正则表达式引擎把行分隔符当做一个字符串分隔符来对待。在使用时,(?m)必须出现在整个模式的最前面。
文本:<script>
function test(value){
//just a test function
if(value!=" "){
//just do it
……
}
}
</script>
正则表达式:(?m)^\s*//.*$
匹配结果:<script>
function test(value){
//just a test function
if(value!=" "){
//just do it
……
}
}
</script>
6、子表达式
子表达式必须用(和)括起来
例如,我们想把一条用户记录里的年份数字完整的记录下来,我们只记录年。
文本:ID:022
SEX:M
DOB:1967-08-17
Status:Active
正则表达式:19|20\d{2}
匹配结果: ID:022
SEX:M
DOB:1967-08-17
Status:Active
分析: 结果只匹配出了19,为什么呢 ,| 表示或操作,为了避免匹配出无意义的年份,正则表达式 19|20\d{2} 的意思是 匹配 19 或者 20\d{2} .那么如何改进呢?使用子表达式:
(19|20)\d{2}
匹配结果:DOB:1967-08-17
7、回溯匹配
(1)回溯
例如:我们想把文本里面所有连续重复出现的单词找出来。
文本 :This is a block of of text, severl words here are are repeated, and and they should not be.
正则表达式 :[ ]+(\w+)[ ]+\1
匹配结果 :This is a blockof of text, severl words here are are repeated, and and they should not be.
\1是一个回溯引用,代表着模式里的第一个子表达式,那么\2就代表模式里的第2个子表达式,依次类推。
(2)替换
例如,我们想把文本段里的邮件文本替换成可以点击的超链接,那么就要用到回溯替换
文本 :Hello, vicky@dut.com is my email address.
正则表达式 :(\w+[\w.]*@[\w.]+\.\w+)
替换 :< A HREF=”mailto:$1”>$1< /A>
8、前后查找
(1)向前查找
以?=开头的子表达式,需要匹配的文本跟在=的后面。向前查找指定了一个必须匹配但不在结果中返回的模式。
正则表达式:.+(?=:)
匹配结果:http://www.forta.com/
为了更好的理解,我们来看一下没有使用向前查找的例子:
正则表达式:.+(:)
匹配结果:http://www.forta.com/
(2)向后查找
使用?<=表示向后查找操作符,也就是查找出现在被匹配文本之前的字符(但不消费他,即不返回在最终的匹配结果里)
文本:ABC01:$23.45
HGG42:$5.31
CFMX1:$899.00
正则表达式:(?<=\$)[0-9.]+
匹配结果:ABC01:$23.45
HGG42:$5.31
CFMX1:$899.00
(3)对前后查找取非
操作符
|
说明
|
(?=)
|
正向前查找
|
(?!)
|
负向前查找
|
(?<=)
|
正向后查找
|
(?<!)
|
负向后查找
|
要想真正的学好、理解好正则表达式,还是要多实践、多练习~共勉