正则表达式
正则表达式(Regular Expression,简称 regex)是一种强大的文本匹配和处理工具,用于在字符串中查找、替换或提取特定模式。以下是正则表达式的主要规则和语法:
1. 基本字符匹配
- 普通字符:直接匹配自身。例如,
a
匹配字符a
。 - 特殊字符:需要转义,例如
.
、*
、+
、?
、^
、$
、()
、[]
、{}
、|
、\
等。- 例如,
\.
匹配字符.
。
- 例如,
2. 字符类
- **
[]
**:匹配括号内的任意一个字符。- 例如,
[abc]
匹配a
、b
或c
。
- 例如,
- **
[^]
**:匹配不在括号内的任意一个字符。- 例如,
[^abc]
匹配非a
、b
、c
的字符。
- 例如,
- 范围:
[a-z]
匹配小写字母,[0-9]
匹配数字。- 例如,
[a-zA-Z0-9]
匹配任意字母或数字。
- 例如,
3. 预定义字符类
- **
.
**:匹配任意单个字符(除了换行符\n
)。 - **
\d
**:匹配数字,等价于[0-9]
。 - **
\D
**:匹配非数字,等价于[^0-9]
。 - **
\w
**:匹配单词字符(字母、数字、下划线),等价于[a-zA-Z0-9_]
。 - **
\W
**:匹配非单词字符,等价于[^a-zA-Z0-9_]
。 - **
\s
**:匹配空白字符(空格、制表符、换行符等)。 - **
\S
**:匹配非空白字符。
4. 量词
- **
*
**:匹配前面的字符 0 次或多次。- 例如,
a*
匹配a
、aa
、aaa
或空字符串。
- 例如,
- **
+
**:匹配前面的字符 1 次或多次。- 例如,
a+
匹配a
、aa
、aaa
等。
- 例如,
- **
?
**:匹配前面的字符 0 次或 1 次。- 例如,
a?
匹配a
或空字符串。
- 例如,
- **
{n}
**:匹配前面的字符恰好n
次。- 例如,
a{3}
匹配aaa
。
- 例如,
- **
{n,}
**:匹配前面的字符至少n
次。- 例如,
a{2,}
匹配aa
、aaa
等。
- 例如,
- **
{n,m}
**:匹配前面的字符至少n
次,至多m
次。- 例如,
a{2,4}
匹配aa
、aaa
或aaaa
。
- 例如,
5. 边界匹配
- **
^
**:匹配字符串的开头。- 例如,
^a
匹配以a
开头的字符串。
- 例如,
- **
$
**:匹配字符串的结尾。- 例如,
a$
匹配以a
结尾的字符串。
- 例如,
- **
\b
**:匹配单词边界。- 例如,
\bword\b
匹配独立的单词word
。
- 例如,
- **
\B
**:匹配非单词边界。
6. 分组和捕获
- **
()
**:将多个字符组合成一个整体,并捕获匹配的内容。- 例如,
(abc)+
匹配abc
、abcabc
等。
- 例如,
- **
(?:)
**:非捕获分组,匹配但不捕获内容。- 例如,
(?:abc)+
匹配abc
、abcabc
等,但不捕获。
- 例如,
7. 选择符
- **
|
**:匹配左边或右边的表达式。- 例如,
a|b
匹配a
或b
。
- 例如,
8. 贪婪与非贪婪匹配
- 贪婪匹配:默认情况下,量词会尽可能多地匹配字符。
- 例如,
a.*b
匹配a
和b
之间的所有字符。
- 例如,
- 非贪婪匹配:在量词后加
?
,尽可能少地匹配字符。- 例如,
a.*?b
匹配a
和b
之间的最短内容。
- 例如,
9. 转义字符
- **
\
**:用于转义特殊字符。- 例如,
\.
匹配字符.
,\*
匹配字符*
。
- 例如,
10. 标志(修饰符)
- **
i
**:忽略大小写。- 例如,
/a/i
匹配a
或A
。
- 例如,
- **
g
**:全局匹配,查找所有匹配项。- 例如,
/a/g
匹配字符串中所有的a
。
- 例如,
- **
m
**:多行模式,^
和$
匹配每行的开头和结尾。- 例如,
/^a/m
匹配每行以a
开头的内容。
- 例如,
11. 零宽断言
- **
(?=)
**:正向先行断言,匹配后面满足条件的位置。- 例如,
a(?=b)
匹配后面是b
的a
。
- 例如,
- **
(?!)
**:负向先行断言,匹配后面不满足条件的位置。- 例如,
a(?!b)
匹配后面不是b
的a
。
- 例如,
- **
(?<=)
**:正向后行断言,匹配前面满足条件的位置。- 例如,
(?<=a)b
匹配前面是a
的b
。
- 例如,
- **
(?<!)
**:负向后行断言,匹配前面不满足条件的位置。- 例如,
(?<!a)b
匹配前面不是a
的b
。
- 例如,
12. 其他
- **
\n
**:匹配换行符。 - **
\t
**:匹配制表符。 - **
\x
**:匹配十六进制字符。- 例如,
\x41
匹配字符A
。
- 例如,
- **
\u
**:匹配 Unicode 字符。- 例如,
\u0041
匹配字符A
。
- 例如,
示例
匹配邮箱地址:
1
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
匹配 URL:
1
/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w\.-]*)*\/?$/
匹配日期(YYYY-MM-DD):
1
/^\d{4}-\d{2}-\d{2}$/
正则表达式的规则非常丰富,掌握这些基本规则后,可以根据实际需求灵活组合使用。
要多次匹配字符串中的所有键值对(如 name=John
、age=25
、city=New York
),可以使用正则表达式的 g
标志(全局匹配),并结合循环或 matchAll
方法。以下是实现方式:
方法 1:使用 match
和 g
标志
1 | var a = /[^=;\s]+=([^=;]+)(?:;?)/g; // 添加 g 标志 |
说明:
match
方法会返回所有匹配的键值对(如name=John
,age=25
,city=New York
)。- 然后对每个键值对再次使用正则表达式提取值部分。
方法 2:使用 matchAll
matchAll
方法可以直接返回所有匹配的详细信息,包括捕获组。
1 | var a = /[^=;\s]+=([^=;]+)(?:;?)/g; // 添加 g 标志 |
说明:
matchAll
返回一个迭代器,每次迭代返回一个匹配结果。match[1]
是捕获组的值部分。
方法 3:使用 exec
和循环
exec
方法可以重复调用,每次返回一个匹配结果。
1 | var a = /[^=;\s]+=([^=;]+)(?:;?)/g; // 添加 g 标志 |
说明:
exec
方法每次调用返回一个匹配结果,直到没有更多匹配。match[1]
是捕获组的值部分。
输出结果
以上三种方法的输出结果均为:
1 | John |
总结
- 使用
g
标志可以实现全局匹配。 match
适合简单的多次匹配。matchAll
和exec
更适合需要捕获组信息的场景。- 根据需求选择合适的方法即可。