# 正则表达式 (Regular Expression)
正则表达式是一种文本模式,用于模式匹配、查找、替换、验证、提取文本数据
正则表达式可以应用于各种编程语言和文本处理工具中
# 语法
# 常用字符
| 字符 | 描述 |
|---|---|
| [ABC] | 匹配 [] 中出现的所有字符。例如:[ABC] 匹配字符串 "AEBECE" 结果为 AEBECE |
| [^ABC] | 匹配除了 [^A] 中出现的所有字符。例如:[^ABC] 匹配字符串 "AEBECE" 结果为 AEBECE |
| [A-Z] | 匹配范围内的所有字符,区分大小写 |
| [\s\S] | 匹配所有 |
| . | 匹配换行符以外的字符 |
| \w | 匹配字母、数字、下划线 |
| \W | 匹配非字母、数字、下划线 |
| \d | 匹配任意数字 |
| \D | 匹配任意非数字 |
| \f | 匹配一个换页符 |
| \n | 匹配一个换行符 |
| \r | 匹配一个回车符 |
| \s | 匹配所有空白符 |
| \S | 匹配所有非空白符,不包括换行 |
| \t | 匹配一个制表符 |
| \v | 匹配一个垂直制表符 |
| \b | 匹配一个单词边界。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项 |
| \B | 非单词边界匹配 |
| \cx | 匹配由 x 指明的控制字符。例如: \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符 |
| \xn | n 为十六进制转义值。正则表达式中可以使用 ASCII 编码 |
| \num | 匹配 num,其中 num 是一个正整数 |
| \nm | 标识一个八进制转义值或一个向后引用 |
| \nml | 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml |
| \un | n 是一个用四个十六进制数字表示的 Unicode 字符 |
| $ | 匹配输入字符串的结尾位置。使用 \ 匹配特殊字符本身 |
| () | 标记一个子表达式的开始和结束位置。用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔 |
| * | 匹配前面的子表达式零次或多次 |
| + | 匹配前面的子表达式一次或多次 |
| ? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符 (非贪婪匹配是最小匹配) |
| . | 匹配换行符以外的字符 |
| \ | 转义符 |
| ^ | 匹配输入字符串的开始位置,当该符号在 [] 表达式中使用时,表示不接受该方括号表达式中的字符集合 |
| [ | 标记一个中括号表达式的开始 |
| { | 标记限定符表达式的开始 |
| | | 指明两项之间的一个选择 |
{n} | 匹配确定的 n 次。 A {n} 表示匹配 ‘A’ n 次 |
{n,} | 至少匹配 n 次 |
{n,m} | 最少匹配 n 次,且最多匹配 m 次 |
| ?= | 正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串。A (?=B) 查找 B 前面的 A |
| ?<= | (?<=B) A 查找 B 后面的 A |
| ?! | 负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。A (?!B) 查找后面不是 B 的 A |
| ?<! | (?<!B) A 查找前面不是 B 的 A 的 |
| ?: | 非捕获。 (?:a) 匹配 a 但是不捕获 a |
# 捕获组
捕获组是用来提取匹配字符串中的子串的一种机制
一个括号就是一个捕获组,它不仅用于逻辑分组(改变运算优先级),还会自动捕获匹配的内容,供后续使用
所有捕获的组都按从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式
group (0) 始终代表整个匹配结果,group (n) 表示第 n 个捕获组
命名捕获组:(?P<name> 表达式),使用 group ("name") 获取命名捕获组
# 反向引用
反向引用是正则表达式中一种用来 引用之前捕获的分组内容 的机制。它允许在模式中或替换操作中重复使用已经匹配的内容
语法:使用 \1 \2 \3 ... 表示之前捕获的组
反向引用的最简单的、最有用的应用之一就是查找文本中两个相同且相邻的单词
字符:A is is the ...
表达式为: \b([a-z]+) \1\b 或 \b([\w]+) \1\b
如果结尾不添加 \b,则会错误的匹配 "is issued" 或 "this is" 等单词
另外 (.)\1+ 可以匹配多个连续的字符
# 非捕获元字符
非捕获组的作用是匹配模式中的内容,但不会将其存储为一个捕获组。这在需要匹配一些内容但不希望占用捕获组编号时非常有用
非捕获元字符 ?: 或 ?= 或 ?! 来重写捕获,忽略对相关匹配的保存
例如: (?:a|b|c)\d 匹配字符 ab2 的结果为 b2 但是 b2 不在捕获组中
例如: (?:https) 在匹配网址的时候匹配 https 但是不捕获
# 修饰符(标记)
标记也称为修饰符,用于指定额外的匹配策略。标记不写在正则表达式里,格式为 /flags 例如 /gi
下表列出了常用的修饰符
| 修饰符 | 描述 |
|---|---|
| i | ignore - 不区分大小写 |
| g | global - 全局匹配 |
| m | multi line - 多行匹配 |
| s | . 匹配换行符 \n |
# 运算符优先级
相同优先级的从左到右进行运算,不同优先级的先高后低,可以使用括号 () 来提升优先级
| 优先级 | 运算符 | 描述 |
|---|---|---|
| 1 | \ | 转义符,用于转义元字符或特殊含义字符 |
| 2 | [] | 字符类,用于匹配字符集合 |
| 3 | () | 分组和捕获,用于分组表达式或指定优先级 |
| 4 | ?,*,+,{} | 量词运算符,用于指定字符或子表达式的重复次数 |
| 5 | ^,$ | 锚点,用于匹配字符串的开头或结尾 |
| 6 | | | 或运算符,用于匹配多个选项中的一个 |
| 7 | 字面值或模式 | 普通字符或模式,用于直接匹配指定字符或表达式 |
# 正则表达式应用
- 捕获组和非捕获组需要根据实际情况自行更改
- 验证用户名和密码(不同平台有不同的规则,以下只是举一个例子)
- 用户名:
^[a-zA-Z]\w{5,15}$ - 密码:
(?!^\\d+$)(?!^[a-zA-Z]+$)(?!^[_#@]+$).{8,}组成,并且第一个字必须为字母 6~16 位
- 用户名:
- 验证手机号码:
^1[3|4|5|7|8][0-9]\d{8}$ - 验证身份证号 (15 位或 18 位数字):
\d{14}[[0-9],0-9xX] - 验证 Email 地址:
\b[\w.%+-]+@[\w.-]+\.[a-zA-Z]{2,}\b或^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$ - 只能输入由数字和 26 个英文字母组成的字符串:
^[A-Za-z0-9]+$ - 整数或小数:
^[-]?[0-9]+([.][0-9]+){0,1}$ - 只能输入数字:
^[0-9]*$ - 只能输入 n 位的数字:
^\d{n}$ - 只能输入至少 n 位的数字:
^\d{n,}$ - 只能输入 m~n 位的数字:
^\d{m,n}$ - 只能输入零和非零开头的数字:
^(0|[1-9][0-9]*)$ - 只能输入有两位小数的正实数:
^[0-9]+(\.[0-9]{2})?$ - 只能输入有 1~3 位小数的正实数:
^[0-9]+(\.[0-9]{1,3})?$ - 只能输入非零的正整数:
^\+?[1-9][0-9]*$ - 只能输入非零的负整数:
^\-[1-9][0-9]*$ - 只能输入长度为 3 的字符:
^.{3}$ - 只能输入由 26 个英文字母组成的字符串:
^[A-Za-z]+$ - 只能输入由 26 个大写英文字母组成的字符串:
^[A-Z]+$ - 只能输入由 26 个小写英文字母组成的字符串:
^[a-z]+$ - 验证是否含有
^ % & ; = ? $ \ " '等字符:[%&',;=?$\\^]+ - 只能输入汉字:
^[\u4e00-\u9fa5]+$ - 验证 URL:
(http[s]?://)?([\w-]+\.)+[\w-]+(/[\w|\.|/|?|%|&|=|_|-]*)? - 验证一年的 12 个月:
^(0?[1-9]|1[0-2])$ - 验证一个月的 31 天:
^((0?[1-9])|((1|2)[0-9])|30|31)$ - 获取日期正则表达式:
\d{4}[年\-\.\/\|\\]0?(1[0-2]|[1-9])[月\-\.\/\|\\]\b0?(3[01]|[12][0-9]|[1-9])\b日? - 匹配双字节字符 (包括汉字在内):
[^\x00-\xff]- 可以用来计算字符串的长度(一个双字节字符长度计 2,ASCII 字符计 1)
- 匹配空白行的正则表达式:
\n\s*\r- 可以用来删除空白行
- 匹配 HTML 标记的正则表达式:
<(\w+)([^>]*?)>(.*?)</\1>|<(\w+)([^>]*?)\s?/>- 这个方法只能匹配简单的 HTML 标记
- 匹配首尾空白字符的正则表达式:
^\s*|\s*$- 可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等)
- 匹配帐号是否合法(字母开头,允许 5-16 字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$- 表单验证时很实用
- 匹配腾讯 QQ 号:
[1-9][0-9]{4,}- 腾讯 QQ 号从 10 000 开始
- 匹配中国邮政编码:
^[1-9]\d{5}$- 中国邮政编码为 6 位数字
- 匹配 IPv4 地址:
\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b - 匹配 MAC 地址:
([0-9A-Fa-f]{2}[:|-]){5}[0-9A-Fa-f]{2}