简单来说,正则表达式就是一套用“符号”代替“文字”来描述字符串的规则公式。可用于:查找、替换、提取、验证文本。一、基本组成:普通字符:直接匹配自身,如:a、1、中。元字符:有特殊含义的符号。如:. * + ? ^ $ [ ] { } ( ) \ |二、常用元字符:元字符含义.匹配除换行符外的任意单个字符^匹配字符串开始位置$匹配字符串结束位置*匹配前面的子表达式零次或多次+匹配前面的子表达式一次或多次?匹配前面的子表达式零次或一次{n}匹配前面的子表达式恰好n次{n,}匹配至少n次{n,m}匹配n到m次[xyz]字符类,匹配方括号中的任意一个字符[^xyz]否定字符类,匹配不在括号中的任意字符(x)捕获组,匹配x并记住该匹配(?:x)非捕获组,匹配x但不记住`xy`\转义字符,将元字符转义为普通字符三、预定义字符类(简写)\d——数字,等价于[0-9]\D——非数字\w——单词字符,等价于[A-Za-z0-9_]\W——非单词字符\s——空白字符(空格、制表符、换行等)\S——非空白字符.——任意字符(默认不包含换行)四、量词的贪婪与懒惰默认量词是贪婪的,会尽可能多的匹配。在量词后加?可变为懒惰(尽可能少匹配)a.*b贪婪:在“aabab”中匹配整个aababa.*?b懒惰:匹配到第一个“aab”和“ab”五、边界断言\b 单词边界 如:\bcat\b 匹配独立的"cat"\B 非单词边界^/$ 一行的开始与结束(多行模式下作用到每行)六、零宽断言(环视)不消耗字符。只判断位置前后是否满足条件:(?=pattern)——正向前瞻,后面是pattern(?!pattern)——负向前瞻,后面不是pattern(?<=pattern)——正向后瞻,前面是pattern(?<!pattern)——负向后瞻,前面不是pattern七、常用修饰符(标志)i——忽略大小写g——全局匹配(找到所有匹配,而非在第一个匹配后停止)m——多行模式,^和$匹配每一行的开始/结束s——允许,匹配换行符(单行模式)手机号:写法:^1[3-9]\d{9}$为什么这么写:^和$强制匹配整个字符串。如果不加,“abc13800138000xyz”也会匹配成功,这会在验证表单时误判。用锚点就是告诉程序:这个字符串只能是手机号,前后不能有多余字符。11是手机号固定的开头,运营商规则。[3-9]第二位数字目前只有3-9(如:13x、15x、18x等)不存在0、1、2开头的手机号,用[3-9]而不是\d可以第一时间过滤明显错误的手机号。\d{9}除去前两位数,后面还剩下9位数字。写成\d{9}比写9个\d简洁。和11位手机号吻合。先锚定边界,再逐段根据业务规则限定字符。邮箱:mu@smmna.cn写法:[\w.-]+@[\w-]+(\.[\w-]+)+为什么这么写:[\w.-]+ 用户名部分\w覆盖了字母、下划线、数字,很多邮箱还允许 . 和短横 - ,所以放进字符类里。+表示至少一个字符。@分隔符邮箱固定必须有一个@[\w-]+ 主域名域名允许字母数字和短横,不允许下划线和点(点用于分割子域),所以写成[\w-]+(\.[\w-]+)+ 域名后缀和子域如:example.com里的.com,或mail.example.com.cn的多级域名。把\.和[\w-]+包成一组,在用量词+表示可以出现一次或多次(至少一个后缀)。这样就能匹配.com、.co.uk等。注意:.号必须转义为\. ,因为.是元字符。结构化拆解的思路:根据部分允许的字符集,分段写,再拼起来。日期格式:YYYY-MM-DD写法:^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$--为什么这么写:年份:^\d{4}简单假设4位数字月份:(0[1-9]|1[0-2])我们不能直接用\d{2},否则会出现00、13这种无效月份。使用分组(...|...)指定两种合法情况0[1-9]:01~0901-91[0-2]:10~12110-12用|将二者“或”起来。日期:(0[1-9]|[12]\d|3[01])同样的思路,限制日期的范围。0[1-9]:01~09[12]\d:10~293[01]:30、31现在的这种写法并不校验2月30日这类逻辑错误(一般需要编程判断),但已在字符层做最大限制。这是值域约束的思路:当字符位置有限制时,用字符类和分支列出合法范围,避免接受非法值。强密码:(至少包含大小写、数字、特殊字符)常见写法:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])^.{8,}$为什么这么写:使用了多个正向前瞻(?=...)前瞻从当前位置(字符串开头)开始向后检查,但不消耗字符。多个前瞻可以并列,同时检查不同条件。(?=.*[a-z]):至少有一个小写字母(?=.*[A-Z]):至少有一个大写字母(?=.*\d):至少有一个数字(?=.*[!@#$%^&*]):至少有一个特殊字符每个?=...里面的.*表示“任意字符出现任意次,知道遇到指定字符”,从而检测是否存在。最后^.{8,}$在所有条件检查完后,再正式匹配整个字符串,且长度至少为8位,如果不加这个,前瞻完成就会匹配空字符串。这是多重判断的经验用法:零宽断言不消耗字符,可堆叠条件,最后再用普通模式整体匹配。提取网址:写法:https?://[^\s/$.?#].[^\s]*为什么这么写:https?匹配http或https,?表示s可有可无。://固定分隔符[^\s/$.?#]用排除型字符类定义“第一个不能是空白、/、$、?、#等”的字符,避免匹配到http://后面直接跟路径分隔符的情况。原理:域名起始不能是这些符号。[^\s]*后面跟任意个非空白字符,覆盖路径、参数、片段,直到遇见空白结束。这样就能从文本中准确切出完整的URL,且不会被空白截断。
简单来说,正则表达式就是一套用“符号”代替“文字”来描述字符串的规则公式。可用于:查找、替换、提取、验证文本。
一、基本组成:
二、常用元字符:
元字符
含义
.
匹配除换行符外的任意单个字符
^
匹配字符串开始位置
$
匹配字符串结束位置
*
匹配前面的子表达式零次或多次
+
匹配前面的子表达式一次或多次
?
匹配前面的子表达式零次或一次
{n}
匹配前面的子表达式恰好n次
{n,}
匹配至少n次
{n,m}
匹配n到m次
[xyz]
字符类,匹配方括号中的任意一个字符
[^xyz]
否定字符类,匹配不在括号中的任意字符
(x)
捕获组,匹配x并记住该匹配
(?:x)
非捕获组,匹配x但不记住
`x
y`
\
转义字符,将元字符转义为普通字符
三、预定义字符类(简写)
四、量词的贪婪与懒惰
默认量词是贪婪的,会尽可能多的匹配。在量词后加?可变为懒惰(尽可能少匹配)
五、边界断言
六、零宽断言(环视)
不消耗字符。只判断位置前后是否满足条件:
七、常用修饰符(标志)
手机号:
先锚定边界,再逐段根据业务规则限定字符。
邮箱:mu@smmna.cn
日期格式:YYYY-MM-DD
强密码:(至少包含大小写、数字、特殊字符)
常见写法:(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])^.{8,}$
为什么这么写:
提取网址:
写法:https?://[^\s/$.?#].[^\s]*
为什么这么写: