一、概述
英文(Regular Expression),简称Regex
。
用一个字符串来描述一个特征,然后去验证其他字符串是否符合这个特征。
如表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”
那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。
主要作用:
- 测试字符串是否包含某个模式
- 查找替换子串
- 提取子串
二、语法
(一)、普通字符匹配
1、字母数字等
a,0,+,我等
如表达式 "c",在匹配字符串 "abcde" 时
匹配结果是:成功;
匹配到的内容是:"c";
匹配到的位置是:开始于2,结束于3。
如表达式 "bcd",在匹配字符串 "abcde" 时
匹配结果是:成功;
匹配到的内容是:"bcd";
匹配到的位置是:开始于1,结束于4。
2、转义字符
\n,
\t,
\r,
\,
\f,
\a,
^,
$`等
如表达式 "\$d",在匹配字符串 "abc$de" 时
匹配结果是:成功;
匹配到的内容是:"$d";
匹配到的位置是:开始于3,结束于5。
3、unicode字符
\u4e00
如表达式 "\u4e00。",在匹配字符串"他的人品万众无一。"时:
匹配结果是:成功;
匹配到的内容是:"一。";
匹配到的位置是:开始于6,结束于8。
(二)、元字符(预定义字符)匹配
1、\d
和\D
\d
=1个数字字符(digit)字符[0-9]
\D
=1个非数字字符[^0-9]
表达式 "\D\d",在匹配 "abc123" 时
匹配的结果是:成功;
匹配到的内容是:"c1";
2、\W
和\W
\w
=1个单词(word)字符[a-zA-Z0-9_]
\W
=1个非单词字符[^a-zA-Z0-9_]
3、\s
和\S
\s
=1个空白(space)字符 [ \n\r\t\v\f]
\S
=1个非空白字符[^ \n\r\t\v\f]
4、.
1个任意字符(排除\n
或不排除)
表达式 "a.\d",在匹配 "aaa100" 时
匹配的结果是:成功;
匹配到的内容是:"aa1";
匹配到的位置是:开始于1,结束于4。
(三)、边界匹配
1、^
和`###
^
=字符串的开始位置
$
=字符串的结束位置
表达式 "^aaa" 在匹配 "xxx aaa xxx" 时
匹配结果是:失败。
因为 "^" 要求与字符串开始的地方匹配,因此,只有当 "aaa" 位于字符串的开头的时候,"^aaa" 才能匹配
表达式 "^aaa"在匹配"aaa xxx xxx"时
匹配的结果是:成功;
匹配到的内容是:"aaa";
匹配到的位置是:开始于0,结束于3。
表达式 "aaa$" 在匹配 "xxx aaa xxx" 时
匹配结果是:失败。
因为 "$" 要求与字符串结束的地方匹配,因此,只有当 "aaa" 位于字符串的结尾的时候,"aaa$" 才能匹配
2、\b
和\B
\b
=匹配单词边界
\B
=匹配非单词边界
表达式 "\bendB" 在匹配 "weekend,endfor,end" 时
(四)、字符组匹配
-
[abc]
[abc] 匹配1个字符,要么a,要么b,要么c -
[^abc]
匹配1个字符,不是a,b,c中的任意一个 -
[a^bc]
匹配1个字符,是a,^,b,c中的任意一个 -
[0-9]
匹配1个数字字符 -
[a-zA-Z]
匹配1个字母字符 -
[-0-9]
或者[0-9-]
匹配1个字符,要么是数字,要么是- -
[.]
匹配1个点 -
[a|b]
匹配a或|或b -
[\[\]]
匹配[
或]
- [\d]
[\\d]
表达式 "[bcd][bcd]" 匹配 "abc123" 时
匹配的结果是:成功;
匹配到的内容是:"bc";
匹配到的位置是:开始于1,结束于3。
表达式 "[^abc]" 匹配 "abc123" 时
匹配的结果是:成功;
匹配到的内容是:"1";
匹配到的位置是:开始于3,结束于4。
(五)、匹配次数
- ?=0次或1次
- +=至少1次
- *=0次或多次
- {n}=匹配n次
- {n,m}=至少n次,最多m次
- {n,}=至少n次
表达式 "\d+\.?\d*" 在匹配 "It costs $12.5" 时
匹配的结果是:成功;
匹配到的内容是:12.5;
匹配到的位置是:开始于10,结束于14。
(六)、运算符
1、XY
模式ab
,表示a后面是b
2、X|Y
a|b
,表示 一个a或者b
表达式 "Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时
匹配结果是:成功;
匹配到的内容是:"Tom";
匹配到的位置是:开始于4,结束于7。
匹配下一个时
匹配结果是:成功;
匹配到的内容是:"Jack";
匹配到的位置时:开始于15,结束于19。
小括号可限制选择范围
3、(X)
表示分组且捕获X
表达式 "(go\s*)+" 在匹配 "Let's go go go!" 时
匹配结果是:成功;
匹配到内容是:"go go go";
匹配到的位置是:开始于6,结束于14。
4、(?:X)
仅用于分组,不捕获
5、\n
引用前面的捕获组n
//匹配html标签
/<(\w+)>[^<]*\1>/
表达式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 时
匹配结果是:成功;
匹配到的内容是:" 'Hello' "。
再次匹配下一个时,可以匹配到 " "World" "。
三、贪婪和非贪婪模式
(一)、贪婪模式
表达式中{m,n}
, {m,}
, ?
, *
, +
的这些重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。称为贪婪模式。
如:针对字符串"1xxxdxxxd",表达式
1\w+
的匹配结果是1xxxdxxxd
。而不是1x
。
(二)、非贪婪模式
在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。
如:针对字符串"1xxxdxxxd"
- 表达式
1\w+?
的匹配结果是1x
。而不是1xxxdxxxd
。 - 表达式
1\w+?d
的匹配结果是1xxxd
。而不是1xxxdxxxd
。
表达式 "(.*) " 与字符串 "aa
bb
" 匹配时
匹配的结果是:成功;
匹配到的内容是 "aa
bb
" 整个字符串, 表达式中的 "" 将与字符串中最后一个 "" 匹配。?
表达达式 "(.*?) " 匹配同样的字符串时,将只得到 "aa
", 再次匹配下一个时,可以得到第二个 "bb
"。
四、预搜索
(一)、正向预搜索(?=xx)
和(?!xx)
表达式 "Windows (?=NT|XP)" 在匹配 "Windows 98, Windows NT, Windows 2000" 时
将只匹配 "Windows NT" 中的 "Windows ",其他的 "Windows " 字样则不被匹配。
表达式 "do(?!\w)" 在匹配字符串 "done, do, dog" 时
只能匹配中间的"do"。不会匹配done和dog中的do。
(二)、反向预搜索(?<=xx)
和(?
表达式 "(?<=\d{4})\d+(?=\d{4})" 在匹配 "1234567890123456" 时
将匹配除了前4个数字和后4个数字之外的中间8个数字,即56789012。
五、匹配标志
标志 | 说明 |
---|---|
ignorecase | 默认情况下,表达式中的字母是要区分大小写的。 配置为 Ignorecase 可使匹配时不区分大小写。 有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。 |
singleline | 默认情况下,小数点 "." 匹配除了换行符(\n)以外的字符。 配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。 |
multiline | 默认情况下,表达式 ^ 和$ 只匹配字符串的开始 ① 和结尾 ④ 位置。如: ①xxxxxxxxx②\n ③xxxxxxxxx④ 配置为 Multiline 可以使 ^ 匹配 ① 外,还可以匹配换行符之后,下一行开始前 ③ 的位置使 $ 匹配 ④ 外,还可以匹配换行符之前,一行结束 ② 的位置。 |
global | 主要在将表达式用来替换时起作用,配置为 Global 表示替换所有的匹配。 |
六、常见正则表达式
- 零和非零开头的数字
^(0|[1-9][0-9]*)$
- 正数、负数、和小数
^(\-|\+)?\d+(\.\d+)?$
- 非零的正整数
^[1-9]\d*$
^([1-9][0-9]*){1,3}$
^\+?[1-9][0-9]*$
- 非零的负整数
^\-[1-9][]0-9"*$
^-[1-9]\d*$
- 非负整数
- `^\d+$``
- ``^[1-9]\d*|0$`
- 非正整数
^-[1-9]\d*|0$
^((-\d+)|(0+))$
- 非负浮点数
^\d+(\.\d+)?$
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
- 非正浮点数
^((-\d+(\.\d+)?)|(0+(\.0+)?))$
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
- 正浮点数
^[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]*))$
- 负浮点数
^-([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]*)))$
- 浮点数
^(-?\d+)(\.\d+)?$
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
- 汉字
^[\u4e00-\u9fa5]{0,}$
- 英文和数字
^[A-Za-z0-9]+$
^[A-Za-z0-9]{4,40}$
- 中文、英文、数字包括下划线
^[\u4E00-\u9FA5A-Za-z0-9_]+$
- Email地址
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
- 域名
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
- InternetURL
[a-zA-z]+://[^\s]*
-
^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?
$
- 手机号码
-
^(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}
$
-
- 电话号码
^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
- 国内电话号码(0511-4405222、021-87888822)
\d{3}-\d{8}|\d{4}-\d{7}
- 身份证号(15位、18位数字)
^\d{15}|\d{18}$
- 短身份证号码(数字、字母x结尾)
^([0-9]){7,18}(x|X)?$
^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
- 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
- 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
^[a-zA-Z]\w{5,17}$
- 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
- 日期格式
^\d{4}-\d{1,2}-\d{1,2}
- 一年的12个月(01~09和1~12)
^(0?[1-9]|1[0-2])$
- 一个月的31天(01~09和1~31)
^((0?[1-9])|((1|2)[0-9])|30|31)$
- xml文件
^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
- 空白行的正则表达式
-
\n\s*\r
(可以用来删除空白行)
-
- HTML标记的正则表达式:
<(\S*?)[^>]*>.*?\1>|<.*? />
- 首尾空白字符的正则表达式(用来删除行首行尾的空白字符)
^\s*|\s*$
(^\s*)|(\s*$)
- 腾讯QQ号(QQ号从10000开始)
[1-9][0-9]{4,}
- 中国邮政编码
[1-9]\d{5}(?!\d)
- IP地址
\d+\.\d+\.\d+\.\d+