什么是正则表达式
正则表达式是一种特殊的字符串模式,用于匹配一组字符串,可以检查一个串是否含有某个子串、将匹配的子串替或者从某个子串中提取符合某个条件的子串。就类似按图索骥,按照给定的某种规则去寻找并匹配目标。
1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题为"神经网事件的表示法"的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为"正则集的代数"的表达式,因此采用"正则表达式"这个术语。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。
正则表达式的介绍
正则表达式是由普通字符(如a-z,0-9,标点符号等)以及特殊字符(成为“元字符”)组成的文字模式。如:/^[0-9]+abc$/。
1. 字符语义介绍
普通字符 没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。
非打印字符
| 表达式 | 描述 |
|---|---|
| \cx | x知名的控制字符,如\cM即为Control-M |
| \f | 换页符 |
| \n | 换行符 |
| \r | 回车符 |
| \s | 任何空白字符,等价于[ \f\n\r\tv] |
| \S | 任何非空白字符,等价于[^ \f\n\r\tv] |
| \t | 制表符 |
| \v | 垂直制表符 |
特殊字符 【需要用反斜杠''进行转义后使用】
| 表达式 | 描述 |
|---|---|
| ^ | 开始标记 |
| $ | 结束标记 |
| () | 子表达式的开始与结束位置,子表达式可供以后使用 |
| * | 子表达式出现n次,n>=0 |
| + | 子表达式m次,m>=1 |
| ? | 子表达式出现0或1次 |
| . | 匹配换行符之外的单个字符 |
| [] | 中括号表达式,用于匹配取值范围,如[0-9]:取数范围0到9;[a-z]:取值范围a-z的字母 |
| {} | 字符长度,如{3-15}:3-15个字符长度 |
| \ | 特殊字符转义符 |
| | | 两项间的选择 |
限定符
| 表达式 | 描述 |
|---|---|
| * | 匹配子表达式n次,n>=0 |
| + | 匹配子表达式m次,m>=1 |
| ? | 匹配子表达式0或1次 |
| {n} | 匹配n次,n为非负整数 |
| {n,} | 至少匹配n次 |
| {n,m} | 匹配至少n次,至多m次 |
定位符【不能将限定符与定位符一起使用】
| 表达式 | 描述 |
|---|---|
| ^ | 字符串开始的位置 |
| $ | 字符串结束的位置 |
| \b | 单词的边界 |
| \B | 非单词的边界 |
元字符
| 表达式 | 描述 |
|---|---|
| ? | 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。如对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o' |
| | (pattern) | 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到 |
| (?:pattern) | 匹配 pattern 但不获取匹配结果。 |
| (?=pattern) | 正向肯定预查(look ahead positive assert), 在任何匹配pattern的字符串开始处匹配查找字符串 |
| (?!pattern) | 正向否定预查(negative assert), 在任何不匹配pattern的字符串开始处匹配查找字符串 |
| (?<=pattern) | 反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反 |
| (?<!pattern) | 反向否定预查,与正向否定预查类似,只是方向相反 |
| x|y | 匹配x或y |
| [xyz] | 匹配xyz的字符 |
| [^xyz] | 匹配xyz以外的字符 |
| [a-z] | a-z范围的任意字符 |
| [^a-z] | a-z以外的任意字符 |
| \d | 匹配一个数字,等价于[0-9] |
| \D | 匹配一个非数字,等价于[^0-9] |
| \w | 匹配字母、数字、下划线,等价于'[A-Za-z0-9_]' |
| \W | 匹配非字母、数字、下划线,等价于 '[^A-Za-z0-9_]' |
| \num | 匹配一个正整数 |
运算符优先级
| 运算符(优先级依次递减) | 描述 |
|---|---|
| |转移符 | |
| (), (?:), (?=), [] | 圆括号和方括号 |
| *, +, ?, {n}, {n,}, {n,m} | 限定符 |
| ^, $, \任何元字符、任何字符 | 定位点和序列(即:位置和顺序) |
| | | \替换,"或"操作 |
匹配规则
基本模式匹配。如:^once$
字符簇。如:[a-z],[^0-9]
确定重复出现。字符簇后面跟花括号,如pattern{2,5}表示pattern匹配2-5次。
备注:? 与 {0,1} 是相等的, * 与 {0,} 是相等的, + 与 {1,} 是相等的。
正则在线工具
附录:常用正则表达式
附录一 校验数字的表达式
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(\.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(\.[0-9]{1,3})?$
非零的正整数:^[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}$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以输入含有’^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+
附录三 特殊需求表达式
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}$
电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号): ((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)
身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
帐号是否合法(字母开头,允许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])[a-zA-Z0-9]{8,10}$
强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在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]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
HTML标记的正则表达式:<(\S*?)[^>]*>.*?|<.*? />
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
参考资料:(文章仅做交流学习,侵权即删!!)