正則表達式
正則表達式(Regular Expression )使用单个字符串来描写叙述、匹配一系列符合某个句法规则的字符串。
在非常多文本编辑器里,正則表達式通常被用来检索、替换那些符合某个模式的文本。正則表達式是由普通字符(全部的大小写字母字符,全部数字,全部标点符号以及一些符号)以及特殊字符(称为元字符,具有特殊含义的字符)组成的文字模式。正則表達式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
正則表達式能够用来:
- (1)验证字符串是否符合指定特征,比方验证是否是合法的邮件地址。
- (2)用来查找字符串。从一个长的文本中查找符合指定特征的字符串。比查找固定字符串更加灵活方便。
- (3)用来替换。比普通的替换更强大。
模式(pattern):一个正則表達式通常被称为一个模式(pattern)。为用来描写叙述或者匹配一系列符合某个句法规则的字符串。
转义字符
转义字符(\)就是把具有特殊意义的字符转化成普通字符。
一些不便书写的字符,比方换行符。制表符等,使用 \n,\t 来表示。
另外有一些标点符号在正則表達式中,被定义了特殊的意义,因此须要在前面加 "\" 进行转义后,匹配该字符本身。
字符 | 描写叙述 |
\cx | 匹配由x指明的控制字符。比如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之中的一个。 否则。将 c 视为一个原义的 'c' 字符。 |
\f | 匹配一个换页符。 等价于 \x0c 和 \cL。 |
\n | 匹配一个换行符。等价于 \x0a 和 \cJ。 |
\r | 匹配一个回车符。 等价于 \x0d 和 \cM。 |
\s | 匹配不论什么空白字符。包含空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 |
\S | 匹配不论什么非空白字符。等价于 [^ \f\n\r\t\v]。 |
\t | 匹配一个制表符。 等价于 \x09 和 \cI。 |
\v | 匹配一个垂直制表符。等价于 \x0b 和 \cK。 |
字符 | 说明 |
^ | 匹配输入字符串的開始位置。要匹配 "^" 字符本身。请使用 "\^" |
$ | 匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "\$" |
( ) | 标记一个子表达式的開始和结束位置。要匹配小括号,请使用 "\(" 和 "\)" |
[ ] | 用来自己定义可以匹配 '多种字符' 的表达式。 要匹配中括号。请使用 "\[" 和 "\]" |
{ } | 修饰匹配次数的符号。要匹配大括号。请使用 "\{" 和 "\}" |
. | 匹配除了换行符(\n)以外的随意一个字符。要匹配小数点本身,请使用 "\." |
? | 修饰匹配次数为 0 次或 1 次。要匹配 "? " 字符本身。请使用 "\? " 当该字符紧跟在不论什么一个其它限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时。匹配模式是非贪婪的。 非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。比如。对于字符串 "oooo",'o+? ' 将匹配单个 "o",而 'o+' 将匹配全部 'o'。 |
+ | 修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "\+" |
* | 修饰匹配次数为 0 次或随意次。要匹配 "*" 字符本身,请使用 "\*" |
| | 左右两边表达式之间 "或" 关系。匹配 "|" 本身。请使用 "\|",分支条件 |
反义
有时须要查找不属于某个能简单定义的字符类的字符。比方想查找除了数字以外。其他随意字符都行的情况,这时须要用到反义。
字符 | 描写叙述 |
\W | 匹配随意不是字母,数字,下划线,汉字的字符 |
\S | 匹配随意不是空白符的字符 |
\D | 匹配随意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的随意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的随意字符 |
修饰匹配次数
限定符用来指定正則表達式的一个给定组件必需要出现多少次才干满足匹配。有*或+或?
或{n}或{n,}或{n,m}共6种。
*、+和?限定符都是贪婪的。由于它们会尽可能多的匹配文字,仅仅有在它们的后面加上一个?
就能够实现非贪婪或最小匹配。
字符 | 描写叙述 |
* | 匹配前面的子表达式零次或多次。 比如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。比如。'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 |
? | 匹配前面的子表达式零次或一次。比如,"do(es)?" 能够匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 |
{n} | n 是一个非负整数。匹配确定的 n 次。比如,'o{2}' 不能匹配 "Bob" 中的 'o',可是能匹配 "food" 中的两个 o。 |
{n,} | n 是一个非负整数。至少匹配n 次。比如。'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的全部 o。 'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 |
{n,m} | m 和 n 均为非负整数,当中n <= m。 最少匹配 n 次且最多匹配 m 次。 比如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。 请注意在逗号和两个数之间不能有空格。 |
贪婪与懒惰
当正則表達式中包括能接受反复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。
以这个表达式为例:a.*b,它将会匹配最长的以a開始,以b结束的字符串。假设用它来搜索aabab的话,它会匹配整个字符串aabab。
这被称为贪婪匹配。
有时。我们更须要懒惰匹配,也就是匹配尽可能少的字符。
前面给出的限定符都能够被转化为懒惰匹配模式。仅仅要在它后面加上一个问号?。这样.*?就意味着匹配随意数量的反复,可是在能使整个匹配成功的前提下使用最少的反复。如今看看懒惰版的样例吧:
a.*?b匹配最短的,以a開始,以b结束的字符串。假设把它应用于aabab的话。它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
代码/语法 | 说明 |
*? | 反复随意次,但尽可能少反复 |
+? | 反复1次或很多其它次,但尽可能少反复 |
? ? | 反复0次或1次,但尽可能少反复 |
{n,m}? | 反复n到m次。但尽可能少反复 |
{n,}? | 反复n次以上。但尽可能少反复 |
字符集合
能够匹配 '多种字符' 当中的随意一个字符。比方。表达式 "\d" 能够匹配随意一个数字。尽管能够匹配当中随意字符,可是仅仅能是一个。不是多个。
表达式 | 可匹配 |
\d | 随意一个数字。0~9 中的随意一个<==>[0-9] |
\w | 随意一个字母或数字或下划线或汉字,也就是 A~Z,a~z,0~9,_,中文 中随意一个 |
\s | 包含空格、制表符(tab)、换页符、换行符等空白字符的当中随意一个<==>[ \f\r\t\n] |
. | 小数点能够匹配除了换行符(\n)以外的随意一个字符 |
使用方括号 [ ] 包括一系列字符,可以匹配当中随意一个字符。用 [^ ] 包括一系列字符。则可以匹配当中字符之外的随意一个字符。
相同的道理,尽管可以匹配当中随意一个,可是仅仅能是一个,不是多个。
表达式 | 可匹配 |
[ab5@] | 匹配 "a" 或 "b" 或 "5" 或 "@" |
[^abc] | 匹配 "a","b","c" 之外的随意一个字符 |
[f-k] | 匹配 "f"~"k" 之间的随意一个字母 |
[^A-F0-3] | 匹配 "A"~"F","0"~"3" 之外的随意一个字符 |
字符边界
字符 | 描写叙述 |
\b | 匹配单词的開始或结束,<==>^加上$ |
^ | 匹配字符串的開始, |
$ | 匹配字符串的结束 |
分组{}
我们已经提到了怎么反复单个字符(直接在字符后面加上限定符即可了)。但假设想要反复多个字符又该怎么办?你能够用小括号来指定子表达式(也叫做分组)。然后你就能够指定这个子表达式的反复次数了,你也能够对子表达式进行其他一些操作。
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个总体也就是这个分组)反复3次,最后再加上一个一到三位的数字(\d{1,3})。
经常使用正則表達式
校验数字的表达式
1 数字:^[0-9]*$ 2 n位的数字:^\d{n}$ 3 至少n位的数字:^\d{n,}$ 4 m-n位的数字:^\d{m,n}$ 5 零和非零开头的数字:^(0|[1-9][0-9]*)$ 6 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?
$
7 带1-2位小数的正数或负数: ^(\-)?\d+(\.\d{1,2})?$ 8 正数、负数、和小数: ^(\-|\+)?\d+(\.\d+)?$
9 有两位小数的正实数: ^[0-9]+(.[0-9]{2})?$
10 有1~3位小数的正实数: ^[0-9]+(.[0-9]{1,3})?$ 11 非零的正整数: ^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$ 12 非零的负整数: ^\-[1-9][]0-9" *$ 或 ^-[1-9]\d*$ 13 非负整数: ^\d+$ 或 ^[1-9]\d*|0$ 14 非正整数: ^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ 15 非负浮点数: ^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16 非正浮点数: ^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17 正浮点数: ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ 18 负浮点数: ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ 19 浮点数: ^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$校验字符的表达式
1 汉字:^[\u4e00-\u9fa5]{0,}$ 2 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ 3 长度为3-20的全部字符:^.{3,20}$ 4 由26个英文字母组成的字符串:^[A-Za-z]+$ 5 由26个大写英文字母组成的字符串:^[A-Z]+$ 6 由26个小写英文字母组成的字符串:^[a-z]+$ 7 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$ 8 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$ 9 中文、英文、数字包含下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$ 10 中文、英文、数字但不包含下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ 11 能够输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 12 禁止输入含有~的字符:[^~\x22]+
特殊需求表达式
1 Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ 2 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.? 3 InternetURL:[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?
$
4 手机号码: ^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$ 5 电话号码( " XXX-XXXXXXX "、 " XXXX-XXXXXXXX "、 " XXX-XXXXXXX "、 " XXX-XXXXXXXX "、 " XXXXXXX "和 " XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$ 6 国内电话号码( 0511- 4405222、 021- 87888822): \d{3}-\d{8}|\d{4}-\d{7} 7 身份证号(15位、18位数字): ^\d{15}|\d{18}$ 8 短身份证号码(数字、字母x结尾): ^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$ 9 帐号是否合法(字母开头。同意5-16字节,同意字母数字下划线): ^[a-zA-Z][a-zA-Z0-9_]{4,15}$ 10 password(以字母开头。长度在6~18之间,仅仅能包括字母、数字和下划线): ^[a-zA-Z]\w{5,17}$ 11 强password(必须包括大写和小写字母和数字的组合。不能使用特殊字符。长度在8-10之间): ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12 日期格式: ^\d{4}-\d{1,2}-\d{1,2} 13 一年的12个月( 01~09和1~ 12): ^(0?[1-9]|1[0-2])$ 14 一个月的31天( 01~09和1~ 31): ^((0?[1-9])|((1|2)[0-9])|30|31)$ 15 钱的输入格式: 16 1.有四种钱的表示形式我们能够接受: " 10000.00 " 和 " 10,000.00 ", 和没有 " 分 " 的 " 10000 " 和 " 10,000 ": ^[1-9][0-9]*$ 17 2.这表示随意一个不以0开头的数字,可是,这也意味着一个字符 " 0 "不通过,所以我们採用以下的形式: ^(0|[1-9][0-9]*)$ 18 3.一个0或者一个不以0开头的数字.我们还能够同意开头有一个负号: ^(0|-?[1-9][0-9]*)$ 19 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,由于钱总不能是负的吧.以下我们要加的是说明可能的小数部分: ^[0-9]+(.[0-9]+)?$ 20 5.必须说明的是,小数点后面至少应该有1位数,所以 " 10. "是不通过的,可是 " 10 " 和 " 10.2 " 是通过的: ^[0-9]+(.[0-9]{2})?$ 21 6.这样我们规定小数点后面必须有两位,假设你觉得太苛刻了,能够这样: ^[0-9]+(.[0-9]{1,2})?$ 22 7.这样就同意用户仅仅写一位小数.以下我们该考虑数字中的逗号了,我们能够这样: ^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$ 23 8.1到3个数字,后面跟着随意个 逗号+3个数字,逗号成为可选,而不是必须: ^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$ 24 备注:这就是终于结果了,别忘了 " + "能够用 " * "替代假设你觉得空字符串也能够接受的话(奇怪,为什么? )最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里 25 xml文件: ^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$ 26 中文字符的正則表達式: [\u4e00-\u9fa5] 27 双字节字符: [^\x00-\xff] (包括汉字在内,能够用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))28 空白行的正則表達式: \n\s*\r (能够用来删除空白行) 29 HTML标记的正則表達式: <(\S*?)[^>]*>.*?
</\1>|<.*? /> (网上流传的版本号太糟糕。上面这个也仅仅能部分。对于复杂的嵌套标记依然无能为力)
34 IP地址:((?
:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))