正则表达式⯐
概述
正则表达式(RegExp)是匹配、检索、替换字符串规则的语法模板,用来快速校验格式、提取内容、批量替换文本。
为什么需要正则表达式
以邮政编码校验为例,对比传统方法和正则表达式检验的区别。
邮政编码规则
- 总长度固定:必须严格 6 位字符,不能多、不能少;
- 字符类型:只能是纯阿拉伯数字 0–9,不允许字母、汉字、空格、符号;
- 首尾规范:第一位不能为
0(常规通用校验规则),后5位可为任意数字; - 无空值:不允许空白、不全、补零占位;
- 无拼接:不能有加号、横杠、括号等分隔符,纯6位连续数字。
| 验证邮政编码,6位数字 | |
|---|---|
源代码
正则表达式语法
正则由普通字符 + 元字符 + 限定符 + 修饰符组成,用来匹配字符串规则。
- 普通字符:仅作字面匹配、无特殊语义的基础字符。
- 元字符:拥有特殊含义的字符,用来描述字符串模式。
- 限定符:用来限制元字符的匹配次数。
- 修饰符:用来改变正则表达式的匹配行为。
-
a|b匹配表达式a或者b,例如/Hello (World|Kitty)!/可以匹配"Hello World!"或"Hello Kitty!" -
[abc]匹配方括号中的任意字符,例如/[drz]oom/可以匹配"doom"、"room"或"zoom" -
[^abc]匹配不在方括号中的任意字符 -
[0-9]匹配任意从0到9的数字,例如/No[3-6]/可以匹配"No3"、"No4"、"No5"、"No6" -
[a-z]匹配任意从a到z的小写字母,[A-Z]匹配任意从A到Z的大写字母。数字、小写、大写字母三种范围可以组合使用,例如/[7-8c-eF-H]/可以匹配字符7、8、c、d、e、F、G、H;/[^0-9a-zA-Z]/可以匹配除了数字和字母以外的任意字符。
元字符,拥有特殊含义的字符:
-
.匹配除了换行符(\n)以外的任何单个字符 -
\d匹配一个数字字符,等价于[0-9] -
\D匹配一个非数字字符,等价于[^0-9] -
\t匹配一个制表符 -
\n匹配一个换行符 -
\r匹配一个回车符 -
注意:Windows下每行结尾使用
\r\n,Unix/Linux下只有\n -
\s匹配任何空白字符(空格、换行、回车、制表符……) -
\S匹配任何非空白字符 -
\w匹配单词字符,等价于[A-Za-z0-9_] -
\W匹配非单词字符,等价于[^A-Za-z0-9_]
*\unnnn 匹配一个unicode字符,nnnn为16进制unicode编码,例如 /[\u4e00-\u9fa5]/ 匹配所有中文字符
\xnn匹配一个ASCII字符,例如/[\x00-\xff]/匹配所有ASCII字符
匹配字符位置:
-
^匹配字符串开头位置,例如/^h/可以匹配"hello"中的"h",但不能匹配"something"中的"h" -
$匹配字符串结束位置,例如/h$/可以匹配"length"中的"h",但不能匹配"something"中的"h" -
\b匹配单词边界,例如/or\b/可以匹配"for you"或者"yes or no"中的"or",但不能匹配"orange"中的"or" -
\B匹配非单词边界 -
(?=s)正向预查,匹配表达式s前面的位置,例如/Windows (?=XP|98)/可以匹配"Windows XP"或"Windows 98"中的"Windows",但不能匹配"Windows 7"中的"Windows" -
(?!s)负向预查,匹配不在表达式s前面的位置,例如/Windows (?!XP)/可以匹配除了在"XP"前面之外的"Windows"字符串
量词,匹配出现次数:
-
{n}匹配前面的表达式n次,例如/[A-Z]{3}/匹配任意三个大写字母,如"CPU"、"IBM",但不能匹配"W3C" -
{n,m}匹配前面的表达式最少n次,最多m次(n<=m),例如/\d{6,8}/可以匹配"123456","7654321","88888888" -
{n,}匹配前面的表达式最少n次,例如/go{2,}gle/可以匹配"google"、"gooogle"、"goooooooooooogle" -
*匹配前面的表达式零次或多次,例如/#\d*/可以匹配"#"、"#1"、"#256"、"#28875474932" -
+匹配前面的表达式一次或多次,例如/ah+/可以匹配"ah"、"ahh"、"ahhhhhhhhh" -
?匹配前面的表达式零次或一次,例如/apples?/可以匹配"apple"或"apples"
转义字符:\
需要转义的字符:\ / ^ $ * + ? { } [ ] ( ) . |
例如:
-
/^\$\d+\.\d{2}$/可以匹配"$123.45"、"$0.25"等 -
/^\*\.(html|js|css)$/可以匹配".html"、".js"、"*.css" -
/^\(\d{3,4}\)\d{8}$/可以匹配"(0431)88951212"、"(010)82619957"等 -
/^[_\$A-Za-z][_\$A-Za-z0-9]*$/可以匹配"hello"、"$123"、"_user"、"num10"
示例
| 编码 | 规则 | 示例 | 正则表达式 |
|---|---|---|---|
| 手机号码 | 1. 一共11位数字; 2. 第一位必须是1; 3. 第第二位可以是3、5、8 |
"13712345678" | ^1[358]\d{9}$ |
| QQ号码 | 大于或等于10000的数字 | "10001" | ^[1-9]\d{4,}$ |
| 浮点数 | 1. 前面可以带负号; 2. 整数至少1位; 3. 小数任意位可以没有小数位 |
"3.14159" | ^-?\d+(\.\d+)?$ |
| 带区号和分机号的电话号码 | 1. 城市区号必须以0开头,共3位或4位; 2. 电话号8位; 3. 分机号3位,分机号部分可有可无 |
"(0431)88951212-152" | ^\(0\d{2,3}\)\d{8}(-\d{3})?$ |
| 国际电话号码 | 1. 由空格分成4个部分, 2. 第一部分+号后面接1~4位国际区号; 3. 第二部分后面接1~4位国际区号,第二部分3-4位地区号不能以0开始,第三部分3-4位,第四部分4位 |
"+86 431 8895 1212" | ^\+\d{1,4} \d{3,4} \d{3,4} \d{4}$ |
| IP地址 | 1. 由小数点分开的4段; 2. 每段都是0~255之间的数字 |
"10.0.2.15" | ^(?:(?: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]?)$ |
| 电子邮件地址 | 1. @前面至少1个字符(可以是数字、字母、下划线、加减号、小数点,加减号和小数点不能在两端); 2. @后面由.分隔成至少2段; 3. 每段至少1个字符(可以是数字、字母、下划线、减号、小数点,减号和小数点不能在两端) |
"jack@java-fans.com" | ^[a-zA-Z0-9_]([a-zA-Z0-9._+-]*[a-zA-Z0-9_])?@[a-zA-Z0-9_]([a-zA-Z0-9.-]*[a-zA-Z0-9_])?\.[a-zA-Z]{2,}$ |
使用正则表达式进行替换
字符串替换:
正则表达式替换:
使用正则表达式获取匹配
另一个获取匹配的例子:
在匹配时使用获取匹配:
练习
跟在量词后面的问号代表按非贪婪模式匹配(缺省都是贪婪模式,即尽可能多的匹配字符)