正则表达式用于文本内容的查找和替换。
正则表达式内置于其它语言或者软件产品中,它本身不是一种语言或者软件。
. 可以用来匹配任何的单个字符,但是在绝大多数实现里面,不能匹配换行符;
. 是元字符,表示它有特殊的含义,而不是字符本身的含义。如果需要匹配 . ,那么要用 \ 进行转义,即在 . 前面加上 \ 。
正则表达式一般是区分大小写的,但是也有些实现是不区分。
正则表达式
nam.
匹配结果
My name is Zheng.
[ ] 定义一个字符集合;
0-9、a-z 定义了一个字符区间,区间使用 ASCII 码来确定,字符区间在 [ ] 中使用。
- 只有在 [ ] 之间才是元字符,在 [ ] 之外就是一个普通字符;
^ 在 [ ] 中是取非操作。
应用
匹配以 abc 为开头,并且最后一个字母不为数字的字符串:
正则表达式
abc[^0-9]
匹配结果
元字符 | 说明 |
---|---|
[\b] | 回退(删除)一个字符 |
\f | 换页符 |
\n | 换行符 |
\r | 回车符 |
\t | 制表符 |
\v | 垂直制表符 |
\r\n 是 Windows 中的文本行结束标签,在 Unix/Linux 则是 \n。
\r\n\r\n 可以匹配 Windows 下的空白行,因为它将匹配两个连续的行尾标签,而这正是两条记录之间的空白行;
元字符 | 说明 |
---|---|
\d | 数字字符,等价于 [0-9] |
\D | 非数字字符,等价于 [^0-9] |
元字符 | 说明 |
---|---|
\w | 大小写字母,下划线和数字,等价于 [a-zA-Z0-9_] |
\W | 对 \w 取非 |
元字符 | 说明 |
---|---|
\s | 任何一个空白字符,等价于 [\f\n\r\t\v] |
\S | 对 \s 取非 |
\x 匹配十六进制字符,\0 匹配八进制,例如 \x0A 对应 ASCII 字符 10,等价于 \n。
应用
匹配邮箱地址。
正则表达式
[\w.]+@\w+\.\w+
[\w.] 匹配的是字母数字或者 . ,在其后面加上 + ,表示匹配多次。在字符集合 [ ] 里,. 不是元字符;
匹配结果
* 和 + 都是贪婪型元字符,会匹配最多的内容。在后面加 ? 可以转换为懒惰型元字符,例如 *?、+? 和 {m, n}? 。
正则表达式
a.+c
由于 + 是贪婪型的,因此 .+ 会匹配更可能多的内容,所以会把整个 abcabcabc 文本都匹配,而不是只匹配前面的 abc 文本。用懒惰型可以实现匹配前面的。
匹配结果
abcabcabc
\b 可以匹配一个单词的边界,边界是指位于 \w 和 \W 之间的位置;\B 匹配一个不是单词边界的位置。
\b 只匹配位置,不匹配字符,因此 \babc\b 匹配出来的结果为 3 个字符。
^ 匹配整个字符串的开头,$ 匹配结尾。
^ 元字符在字符集合中用作求非,在字符集合外用作匹配字符串的开头。
分行匹配模式(multiline)下,换行被当做字符串的边界。
应用
匹配代码中以 // 开始的注释行
正则表达式
^\s*\/\/.*$
匹配结果
使用 ( ) 定义一个子表达式。子表达式的内容可以当成一个独立元素,即可以将它看成一个字符,并且使用 * 等元字符。
子表达式可以嵌套,但是嵌套层次过深会变得很难理解。
正则表达式
(ab){2,}
匹配结果
ababab
| 是或元字符,它把左边和右边所有的部分都看成单独的两个部分,两个部分只要有一个匹配就行。
正则表达式
(19|20)\d{2}
匹配结果
应用
匹配 IP 地址。
IP 地址中每部分都是 0-255 的数字,用正则表达式匹配时以下情况是合法的:
正则表达式
((25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))\.){3}(25[0-5]|(2[0-4]\d)|(1\d{2})|([1-9]\d)|(\d))
匹配结果
回溯引用使用 \n 来引用某个子表达式,其中 n 代表的是子表达式的序号,从 1 开始。它和子表达式匹配的内容一致,比如子表达式匹配到 abc,那么回溯引用部分也需要匹配 abc 。
应用
匹配 HTML 中合法的标题元素。
正则表达式
\1 将回溯引用子表达式 (h[1-6]) 匹配的内容,也就是说必须和子表达式匹配的内容一致。
<(h[1-6])>\w*?<\/\1>
匹配结果
需要用到两个正则表达式。
应用
修改电话号码格式。
文本
313-555-1234
查找正则表达式
(\d{3})(-)(\d{3})(-)(\d{4})
替换正则表达式
在第一个子表达式查找的结果加上 () ,然后加一个空格,在第三个和第五个字表达式查找的结果中间加上 - 进行分隔。
($1) $3-$5
结果
(313) 555-1234
元字符 | 说明 |
---|---|
\l | 把下个字符转换为小写 |
\u | 把下个字符转换为大写 |
\L | 把\L 和\E 之间的字符全部转换为小写 |
\U | 把\U 和\E 之间的字符全部转换为大写 |
\E | 结束\L 或者\U |
应用
把文本的第二个和第三个字符转换为大写。
文本
abcd
查找
(\w)(\w{2})(\w)
替换
$1\U$2\E$3
结果
aBCd
前后查找规定了匹配的内容首尾应该匹配的内容,但是又不包含首尾匹配的内容。向前查找用 ?= 来定义,它规定了尾部匹配的内容,这个匹配的内容在 ?= 之后定义。所谓向前查找,就是规定了一个匹配的内容,然后以这个内容为尾部向前面查找需要匹配的内容。向后匹配用 ?<= 定义(注: javaScript 不支持向后匹配, java 对其支持也不完善)。
应用
查找出邮件地址 @ 字符前面的部分。
正则表达式
\w+(?=@)
结果
abc @qq.com
对向前和向后查找取非,只要把 = 替换成 ! 即可,比如 (?=) 替换成 (?!) 。取非操作使得匹配那些首尾不符合要求的内容。
条件判断为某个子表达式是否匹配,如果匹配则需要继续匹配条件表达式后面的内容。
正则表达式
子表达式 (\() 匹配一个左括号,其后的 ? 表示匹配 0 个或者 1 个。 ?(1) 为条件,当子表达式 1 匹配时条件成立,需要执行 ) 匹配,也就是匹配右括号。
(\()?abc(?(1)\))
结果
条件为定义的首尾是否匹配,如果匹配,则继续执行后面的匹配。注意,首尾不包含在匹配的内容中。
正则表达式
?(?=-) 为前向查找条件,只有在以 - 为前向查找的结尾能匹配 \d{5} ,才继续匹配 -\d{4} 。
\d{5}(?(?=-)-\d{4})
结果
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. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在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. 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
27. 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
28. HTML标记的正则表达式:<(\S*?)[^>]*>.*?\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
29. 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
30. 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
31. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
32. IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
33. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
34. 汉字:^[\u4e00-\u9fa5]{0,}$
35. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
36. 长度为3-20的所有字符:^.{3,20}$
37. 由26个英文字母组成的字符串:^[A-Za-z]+$
38. 由26个大写英文字母组成的字符串:^[A-Z]+$
39. 由26个小写英文字母组成的字符串:^[a-z]+$
40. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
41. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
42. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
43. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
44. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 12 禁止输入含有~的字符:[^~\x22]+