正则表达式
方法
在JavaScript中,实际执行匹配操作的是字符串对象(如 String
),正则表达式只是一种匹配规则,常用的字符串匹配方法有:
String.prototype.match(regexp)
- 检索与正则表达式相匹配的结果,返回一个匹配结果数组或
null
- 检索与正则表达式相匹配的结果,返回一个匹配结果数组或
String.prototype.search(regexp)
- 执行一个正则表达式匹配搜索,并返回第一个匹配项在字符串中的索引,没有找到则返回 -1
String.prototype.replace(regexp|substr, newSubStr|function)
- 在字符串中查找匹配项并替换它们
String.prototype.split(separator, limit)
- 将正则表达式或固定字符串作为分隔符来分割字符串,返回字符串数组
RegExp
对象的方法:
test(string)
- 返回布尔值,表示是否匹配到了正则表达式
exec(string)
- 结果同
String.prototype.match(regexp)
- 结果同
匹配规则
- 字符匹配:
- 直接字符:匹配该字符本身,如
a
匹配字符 ‘a’ .
(点):匹配除换行符\n
之外的任何单个字符(包括标点符号)
- 直接字符:匹配该字符本身,如
- 字符集合(写在
[]
内的):[abc]
:匹配集合中的任意一个字符,如a
、b
或c
。[a-z]
:匹配任何小写字母。[A-Z]
:匹配任何大写字母。[0-9]
:匹配任何数字。[^abc]
:匹配不在集合中的任意字符,如^
在集合开头表示否定。
- 量词(在匹配内容后):
*
:0次或多次+
:1次或多次?
:0次或1次{n}
:n次{n,}
:至少n次{n,m}
:至少n次,至多m次
- 边界匹配:
^
:匹配字符串以什么开头(在多行模式下可以匹配每行的开始),比如:^abc
:匹配以 “abc” 开头的字符串。[^a-z]
:匹配任何不是小写字母的单个字符。
$
:匹配字符串以什么结束\b
:不匹配任何字符,而是匹配一个位置,满足一侧是字符,另一侧不是,通常用于匹配一个单词- 假如
"hello world!"
想要匹配完整的单词"hello"
而不是"hello"
中的一部分,因为"hello"
前后都是非单词字符(这里是空格和字符串的结束),使用\bhello\b
可以实现这一点
- 假如
\B
:匹配非单词边界,不常用
- 分组与引用:
()
:将括号内的表达式作为一个整体进行匹配,而[]
将匹配集合中的任何一个\n
(n 是一个正整数):返回第n个匹配到的字符
- 转义字符:
\
:用于转义特殊字符,使其失去特殊含义,或表示无法直接输入的字符(如换行符\n
)。
- 选择符:
|
:“或”操作,匹配左边或右边的表达式- 与:直接对多个条件进行拼接,例如
abc
,等同于(abc)
- 非:
!
运算符,用零宽度断言来表示,例如/(?<!\d)w+/
表示
- 预定义字符集:
\d(digital)
:匹配一个数字字符,等价于[0-9]
。\D
:匹配一个非数字字符,等价于[^0-9]
。\w(word)
:匹配包括下划线的任何单词字符,等价于[A-Za-z0-9_]
。\W
:匹配任何非单词字符,等价于[^A-Za-z0-9_]
。\s(space)
:匹配任何空白字符,包括空格、制表符、换页符等\S
:匹配任何非空白字符
- 匹配模式(加在末尾):
/ /i
:忽略大小写,例如:/hello/i
会匹配HelLo,hellO等/ /g
:全局匹配,例如:/ab/g
会匹配“ababa”中所有“ab”子串
- 零宽度断言(只确认不消耗):
- 正向先行断言
?=
:匹配内容后挨着什么,例如/\d(?=[a-z])/
表示要匹配的数字后面应该紧跟着一个小写字母 - 负向先行断言
?!
:匹配内容后不挨着什么 - 正向后行断言
?<=
:匹配内容前挨着什么,例如/\d(?<=[a-z])/
表示匹配的数字前面应该有一个字母 - 负向后行断言
?<!
:匹配内容前不挨着什么
- 正向先行断言
应用场景扩展
-
验证用户输入
let emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; // emailRegex.test(email) 验证是否符合条件
正则:开头[\s@]匹配不含空格和@的一到多个字符,然后匹配一个@,后面继续匹配不含空格和@开头的一到多个字符,然后匹配一个
.
,后面继续匹配不含空格和@开头的一到多个字符,然后结尾 -
解析URL的查询字符串
// 查询字符串部分 let href = 'https://example.com/page?name=John&age=30&city=New+York'; // 提取查询字符串部分 let queryString = href.split('?')[1]; let data = {}; let reg = new RegExp('([^?=&]+)(=([^&]*))?', 'g'); queryString.replace(reg, function($0, $1, $2, $3) { if ($3) { data[$1] = decodeURIComponent($3); // 使用decodeURIComponent来解码可能存在的URL编码 } else { data[$1] = true; // 或者 data[$1] = null; } });
全局搜索整个字符串中所有符合以下模式的子串:
- 第一个捕获组([^?=&]+):匹配一个或多个不是
?
、=
或&
的字符,也就是参数名 - 第二个捕获组(=([^&]*))?:加了
?
为可选捕获组,匹配0或多个不是&
的字符,也就是参数值
/
实际也许不需要replace函数的替换功能,但是可以利用它在替换时的回调函数来做一些事情 - 第一个捕获组([^?=&]+):匹配一个或多个不是
-
过滤和筛选数据
let words = ["apple", "banana", "grapefruit", "orange", "grape"]; let filteredWords = words.filter(word => /grape/.test(word));
正则:验证数组中的每一个单词中是否含有整个
grape
,结果为返回["grapefruit", "grape"]
-
分割字符串
const generateText = (template: string, replacements: any[]) => { let index = 0; return template.split(/XX/).map((part) => index < replacements.length ? `${part}${replacements[index++]}` : part ).join(''); };