正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
特点:
1. 灵活性、逻辑性和功能性非常强;
2. 可以迅速地用极简单的方式达到字符串的复杂控制。
使用正则表达式实现对用户名的限制代码
^(?![A-Za-z0-9]+$)(?![a-z0-9\W]+$)(?![A-Za-z\W]+$)(?![A-Z0-9\W]+$)[a-zA-Z0-9\W]{8,}$
1、匹配位置的元字符---^、$、\b
即匹配位置的元字符只有^(脱字符号)、$(美元符号)和\b这三个字符。分别匹配行的开始、行的结尾以及单词的开始或结尾。它们匹配的都只是位置。
1.^匹配行的开始位置。^xxx --- 以xxx开始 ---\bxxx
2.$匹配行的结尾位置。xxx$ --- 以xxx结束 ---xxx\b
3. \b匹配单词的开始或结束。\bxxx\b --- 匹配xxx字符串
2、 匹配字符的元字符---. 、\w、\W、\s、\S、\d、\D
其中.(点号)表示匹配除换行符之外的任意字符;
- \w 匹配单词字符(不仅仅是字母,还有下划线、数字和汉字)--- 一个\w只匹配一个字符;
- \W匹配任意的非单词字符(注意,与\w刚好相反);
- \s匹配的是任意的空白字符(如空格、制表符、换行符、中文全角空格等);
- \S匹配的是任意的非空白字符(注意:刚好和\s相反);
- \d匹配任意的数字;
- \D匹配任意的非数字字符(注意:刚好和\d相反)。
- ^.$表示匹配一行中的唯一一个任意的非换行符的字符
- \ba\w\w\w\w\w\w\w\w\w\b表示匹配以字母a开始的后面有9个字母字符的单词。 (注意:其中的a并不是元字符,就是一个普通的字符,我们称之为字符串字面值(string literal)-所谓字符串字面值,就是字面上看起来是什么就是什么)
- \b\w\w\w\d\d\d\d\D\b表示匹配以3个字母字符开始后面紧跟着四个数字字符且最后一个不是数字字符的单词。
正则表达式之文字匹配
字符类
字符类可以由[]和几个简单的字母组成。[0123456]可以匹配0123456这七个数字中的任意一个。字符类[]中的多个字符只会匹配其中一个。
我们可以使用 -连字符简写,如[0-6]和<H[1-6]>。可知[0-9]和\d的作用是一样的。[a-z]可以表示所有的小写字母,[A-Z]可以表示所有的大写字母。[a-zA-Z]可以表示所有的大写字母和小写字母。
值得注意的是 -(连字符) 只有在字符类中的中间位置时才是“到”的意思。
[-b]5中-没有在两个字符之间,所以它表示的是-5或者b5。
除此之外,我们知道^时只匹配行的开头,但是如果^出现在字符类中的第一个位置,那么它表示否定该字符类。如[^123]表示匹配不是数字1或2或3的其他任意字符。[^-]表示匹配不是-的任意字符。
字符类中使用元字符(-、^等)时,不需要进行转义运算。
[^aeiou]匹配元音之外的字符、[0-9a-zA-Z_]匹配任何数字、字母(大写和小写)和下划线,这等同于\w、[^0-9a-zA-Z_]匹配任何非数字、字母(大写和小写)和下划线,这等同于\W。
字符转义
元字符如&、^、.等都表示着特殊的涵义,如果我们希望把他们看作一般的字符去匹配字符串,并且恰好他们又都不在字符类(如[&]中),我们就需要使用\(反斜杠)进行转义了。
如我们可以使用www.jb51.net来匹配www.jb51.net。 我们可以用\*来匹配字符串中的*(通配符)。 我们还可以通过\\来匹配\
反义
^再字符类中的最前面时表示对这个字符类中的字符表示否定。如a[^b]匹配a和a后面不是b的字符。又如<asp[^>]>表示匹配<asp和其后面的字符不是>的字符。
正则表达式之限定符
- {n} 表示重复n次,如\w{5}表示匹配个单词字符。
- {n,} 表示重复至少n次,如\w{5}表示匹配至少5个单词字符,也可以是6个,7个……
- {n,m} 表示重复至少n次,最多m次,如\w{5,10} 表示匹配至少5个,最多10个单词字符。
- * 表示重复至少0次。 等同于{0,} ,即hu*t可以匹配ht或hut或huut或huuut……
- + 表示重复至少1次。 等同于{1,},即hu+t可以匹配 hut或huut或huuut……
- ? 表示重复0次或1次。等同于{0,1},即colou?r表示匹配color或者是colour。
上面的限定符所指的i安定都是限定的前面的某一个字符。
限定符之后加上一个?,称之为懒惰限定符。我们称上面几种匹配为贪婪匹配。
- {n}? 等同于{n}
- {n,}? 尽可能少的使用重复,但至少使用n次
- {n,m}? 重复n次到m次之间,但要尽可能少的使用重复。
- *? 尽可能少的使用重复的第一个匹配
- +? 尽可能少的使用重复,但至少使用1次
- ?? 使用零次重复(如果有可能)或者一次重复
正则表达式之字符的运算
替换
什么是替换呢? 显然就是指一个不行,我用另一个来替换,比如0\d{3}-\d{7}|0\d{2}-\d{8} 就表示匹配前4位为区号、后7位为本地号码的电话号码,亦可匹配前3位为区号、后8位为本地号码的电话号码。| 表示的就是替换了。 又如[Jj]ack和Jack|jack的匹配效果是一样的都是用来匹配Jack或jack的。也就是说,替换|是或运算的关系。
或运算:0 0结果为0,0 1结果为1,1 0结果为1,1 1结果为1。那么在正则表达式中同样是这样,如果一个都匹配不上就不匹配;如果有一个能匹配上就匹配一个;如果两个都能匹配上,就匹配两个。
分组
正则表达式中,分组也是一个非常重要的概念。看似复杂,实际上分组就是使用"("和")",即左圆括号和右圆括号将某些字符括起来看成一个整体来处理。
比如我们希望匹配abcabc。如果是abc{3}匹配的就是abccc,这不能达到预期,所以我们可以对abc分组,即(abc){3}就可以匹配到我们想要的字符串了。
反向引用
上面我们通过()可以进行分组,而分组的同时,每一个组被自动赋予了一个组号,该组号可以代表该组的表达式。
编组的规则是:从左到右、以分组的左括号"("为标志,第一个分组的组号为1,第二个分组的组号为2,以此类推。
- \数字,使用数字命名的反向引用。注:这个是通用的一种方式。---\b(\w)\1\b --- aa
- \k<name>,使用指定命名的反向引用。注:这个是.NET Frameword支持的一种方式。
另外,下面几个也是常用的分组:
- (?=expression)匹配字符串expression前面的位置
- (?!expression)匹配后面不是字符串expression的位置
- (?<=expression)匹配字符串expresssion后面的位置
- (?<!expression)匹配前面不是字符串expression的位置
- (?>expression)只匹配字符串expression一次
零宽度断言
之前介绍的^和$都是匹配的一个满足一定条件的位置。这里把满足的一个条件成为断言或零宽度断言。
常用的有:
- ^ 匹配行的开始位置
- $ 匹配行的结束位置
- \A 匹配必须出现在字符串的开头
- \Z 匹配必须出现在字符串的结尾或字符串结尾处的\换行符好n之前
- \z 匹配必须出现在字符串的结尾
- \G 匹配必须出现在上一个匹配结束的地方
- \b 匹配字符的开始或结束位置
- \B 匹配不是在字符的开始或结束位置
之前所提到的(?=expression)、(?!expression)、(?<=expression)、(?<!expression)也都是匹配一个位置。
(?=expression)称为零宽度预测先行断言,它断言自身位置的后面能够匹配表达式expression。如\b\w+(?=ed\b)可以匹配以字符串ed结尾的单词的前面部分,如reseted中的reset。
(?<=expression)又称为零宽度正回顾后发断言,它断言自身位置的前面能够匹配表达式expression。
负向零宽度断言
(?!expression)称为负向零宽度断言,即断言自身位置的后面不能匹配字符串expression。
如\b\w{3}(?!\d)匹配的是后面不是数字的以三个单词字符开头的三个单词字符。如下所示:
优先级顺序
正则表达式中存在元字符、转义符、限定符、|等运算或表达式。在匹配过程中,正则表达式都事先规定了这些运算或表达式的优先级。正则表达式也可以像数学表达式一样来求值。也就是说,正则表达式可以从左到右、并按照一个给定的优先级来求值。
优先级顺序表(优先级由高到低)如下:
- 转义符:\
- 圆括号和方括号:()、(?:)、(?=)、[]
- 限定符: *、+、?、{n}、{n,}、{n,m}
- 位置和顺序:^、$、\(元字符)
- 或运算:|
或运算的优先级是最低的。