前端必须掌握的正则知识

- Published on

前端必须掌握的正则知识
正则表达式(Regular Expression,简写为 regex、regexp)是前端绕不过去的坎。
学习正则时觉得好像挺简单,使用它时又觉得好难。
1. 什么是正则表达式
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
它可以用来操作字符串,如:
- 检索字符串
- 替换字符串
正则表达式可以用形式化语言理论的方式来表达。
正则表达式由常量和算子组成,它们分别表示字符串的集合和在这些集合上的运算。
在 Perl 中就内建了一个功能强大的正则表达式引擎。
JavaScript 中也有正则表达式。
2. 正则表达式基本语法
一个正则表达式通常被称为一个模式,用来描述或者匹配一系列匹配某个句法规则的字符串。
大部分正则表达式的形式都有如下的结构:
- 选择
- 数量限定
- 匹配
2.1 选择
竖线|,代表选择(或集),优先级较低。
如:gray|grey 可以匹配 grey 或 gray.
2.2 数量限定
某个字符串后的数量限定符用来限定前面这个字符允许出现的个数。
常见的数量限定符包括:+、?、*。
- +: 至少出现一次(>= 1),必须得有
- ?: 最多只可以出现一次(0 || 1),简记:有没有都行
- *: 可以不出现,也可以出现一次或者多次(>= 0)
2.3 匹配
圆括号()可以用来定义操作符的范围和优先度。
如:
gr(a|e)y 等价于 gray|grey
圆括号()定义了操作符“|”的范围。
(grand)?father 匹配 father 和 grandfather
圆括号()定义了操作符“?”的范围。
上述这些构造子都可以自由组合;
如:H(ae?|ä)ndel和H(a|ae|ä)ndel是相同的。
因为 ae?和a|ae是等价的。
3. PCRE 表达式
正则表达式有不同的写法,使用最广泛的是 PCRE。
PCRE 的全称是 Perl Compatible Regular Expression,即 Perl 兼容的正则表达式。
各种编程语言如 Java、Python、C#、JavaScript 实现的就是这种正则表达式。
PCRE 表达式(部分): |
总结
- \ 代表特殊字符
- 处理范围问题
- [] 处理字符集合
- () 包含独立的匹配模式块
4. 创建正则表达式
表达式字面量:
var re = /ab+c/;
使用 RegExp 对象的构造函数:
var re = new RegExp("ab+c");
5. 编写一个正则表达式的模式
简单字符正则表达式模式, 如 /abc/
简单和特殊字符的组合, 如/abc/ 或 /Chapter (\d+).\d/
5.1 标志
通过标志可以进行高级搜索。
g : 全局搜索
i : 不区分大小写搜索
m : 多行搜索
s : 允许 . 匹配换行符
u : 使用 unicode 码的模式进行匹配
y : 执行“粘性(sticky)”搜索
var re = /\w+\s/g; var re = new RegExp("\\w+\\s", "g");
6. 使用正则表达式
正则表达式主要做两件事:
- 查找
- 测试
JavaScript 中,正则表达式可以被用于:
- RegExp 的 exec 和 test 方法
- String 的 match、replace、search 和 split 方法
序号 | 字符 | 描述 | 返回值 |
---|---|---|---|
1 | exec | 查找匹配的 RegExp 方法 | 返回一个数组或 null |
2 | test | 测试是否匹配的 RegExp 方法 | Boolean |
3 | match | 查找匹配的 String 方法 | 返回一个数组或 null |
4 | replace | 查找匹配的 String 方法 | 返回一个数组 |
5 | matchAll | 查找所有匹配的 String 方法 | 一个迭代器(iterator) |
6 | search | 测试匹配的 String 方法 | 并且使用替换字符串替换掉匹配到的子字符串 |
7 | split | 分隔一个字符串,将分隔后的子字符串存储到数组中的 String 方法 | 返回一个数组 |
应用示例:
RegExp 的 exec 方法:
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log(myArray);
// ["dbbd", "bb", index: 1, input: "cdbbdbsbz", groups: undefined]
结果:exec 方法会返回匹配结果和其他正则属性。
String 的 match 方法:
var myArray = "cdbbdbsbzdbbbbbbbbdfkk".match(/d(b+)d/g);
console.log(myArray);
// ["dbbd", "dbbbbbbbbd"]
结果:exec 方法会返回匹配结果和其他正则属性。
7. 常见正则
反转字符串:
let re = /(\w+)\s(\w+)/;
let str = "John Smith";
// $1 和 $2 指明括号里先前的匹配
let newstr = str.replace(re, "$2, $1");
console.log(newstr);
// Smith, John
从 URL 中提取子域名:
var url = "http://xxx.domain.com";
console.log(/[^x]+/.exec(url)[0].substr(7));
// /[^.]+/ 的意思是:多个非"."的字符串集合,指匹配“.”之前的字符集合
// logs "xxx"
从 URL 中提取 params:
let url = "http://www.nowcoder.com?key=1&key=2&key=3&key=4&test=4#hehe";
function getUrlParam(sUrl, sKey) {
var result = {};
// “\??“ -> 匹配有0个或1个 "?"
// "(\w+)=(\w+)&?" -> 匹配以“=”相连且0或1个“&”结尾的任意多个字符
sUrl.replace(/\??(\w+)=(\w+)&?/g, function (a, k, v) {
if (result[k] !== void 0) {
var t = result[k];
result[k] = [].concat(t, v);
} else {
result[k] = v;
}
});
if (sKey === void 0) {
return result;
} else {
return result[sKey] || "";
}
}
console.log(getUrlParam(url, key));
判断手机号是否合法:
function isPhoneNum(num) {
if (typeof num === "number") return false;
// 以 1 开头,第二个字符为 [35789] 中任意一个,然后是 9 个数字结尾
let reg = /^1[35789]\d{9}$/g;
return reg.test(num);
}