正则表达式的从入门到入土 含案例
才发现一直没有给正则表达式写个博文,今天正好有空来写写。因为 JS 比较方便测试,打开个网页就可以了,所以下面代码就以 JS 为基础写。
1 创建
- 元字符必须转义:
{}[]\^$|()?*+. - 转义字符:
\
采用字面量创建:var 变量 = /正则表达式/匹配模式
RegExp该类型支持正则表达式,可以创建一个正则表达式
// 下面两种方法是等价的
// 匹配[bc]at,不区分大小写
var pattern4 = /\[bc\]at/i;
var pattern6 = new RegExp("\\[bc\\]at", "i");2 模式
- g:表示匹配所有字符串,应用于所有字符串,不会在匹配到第一个时结束
let str = "The rain in Spain stays mainly in the plain";
let regex = /in/g;
let matches = str.match(regex);
console.log(matches); // 输出: [ 'in', 'in', 'in' ]
- i:不区分大小写
// 匹配含有 hello 的字符串
let str = "Hello World";
let regex = /hello/i;
let result = regex.test(str);
console.log(result); // 输出: true
- m:单行匹配匹配
- 一行一行去匹配
- 影响
^和$的行为,使它们匹配每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾。
// 匹配开头为 Second 的字符串
let str = "First line\nSecond line";
let regex = /^Second/m;
let result = regex.test(str);
console.log(result); // 输出: true
- s:忽略换行符
- 使
.可以匹配包括换行符在内的任何字符。
- 使
let str = "Hello\nWorld";
let regex = /Hello.World/s;
let result = regex.test(str);
console.log(result); // 输出: true
3 规则
这里就不一一演示了,自己试一下就可以,主要看下一章的案例
|:或的意思,例如检查字符串是否存在 a 或 b,/a|b/
[]:里的内容也是或的关系,原子表[ab] == a|b;[a-z]:任意小写字母;[A-Z]任意大写字母;[A-z]任意字母;[0-9]任意数字
[^]:除了,例:[^ae]>不选择 a 和 e 字母
():优先级
{n}:出现 n 次;{m,n}:出现 m 到 n 次;m,:出现 m 次以上
+:至少一个,等价于{1,}
*:0 个或多个,等价于{0,}
?:0 个或 1 个,等价于{0,1},https?表示 s 可能会不存在->http
^:匹配开头,例如检查一个字符串中是否以 a 开头/^a/
$:匹配结尾,边界符
.:除了换行符以外的所有字符
\:转义,例如如果想表示点号则需要\.
?::表示不保留,(?:com|cn)意为我匹配这段但是不保留
\w:任意字母、数字、_[A-z0-9_]\W:除了字母、数字、_[^A-z0-9_]\d:任意的数字[0-9]\D:除了数字[^0-9]\s:匹配任何空白字符,包括空格、制表符、换页符等等。\S:匹配任何非空白字符。\b:单词边界=>单词或非单词之间(意思是,该单词前面或后面不存在内容)看下面例子\B:除了单词边界例:创建一个正则表达式检查一个字符串中是否含有单词 child=>
/\bchild\b/—>'hello child'例:去掉开头和结尾空格=>
/^\s*|\s*$/g匹配任意字符:
(.*?)
4 字符串方法
string.search():搜索指定内容,返回其位置,找不到就-1
let str = "Hello, world!";
let position = str.search(/world/);
console.log(position); // 输出: 7
string.split():返回值是一个通过 reg 切分的数组, 参数二是长度
let str = "apple,banana,cherry";
let array = str.split(/,/);
console.log(array); // 输出: ["apple", "banana", "cherry"]
string.match():将符合条件的内容提取出来
let str = "The rain in Spain stays mainly in the plain";
let matches = str.match(/ain/g);
console.log(matches); // 输出: ["ain", "ain", "ain"]
string.replace():将字符串中指定内容替换为新的内容,两个参数,替换内容和新内容。
let str = "Hello, world!";
let newStr = str.replace("world", "universe");
console.log(newStr); // 输出: "Hello, universe!"
5 正则表达式方法
test():按规则查找,返回 true 和 false
let regex = /hello/i;
let result = regex.test("Hello, world!");
console.log(result); // 输出: true
exec():返回包含第一个匹配项信息的数组,没有匹配项返回 null。- 有两个格外属性:index(匹配项在字符串的位置)和 input(字符串)
let regex = /h(ell)o/;
let result = regex.exec("Hello, world!");
console.log(result);
// 输出: ["Hello", "ell"]
// result.index: 0
// result.input: "Hello, world!"
- 下面的就有点特殊,他们都是 RegExp 的函数。你需要先运行 1+个的正则表达式匹配方法才能使用下面函数。
lastMatch:最近一次匹配项lastParen:最近一次匹配的捕获组leftContext:字符串中 lastMatch 之前的文本multiline:布尔值、是否是多行模式rightContext:字符串中 lastMatch 之后的文本
let regex = /(foo)bar/;
let str = "foobar";
regex.test(str); // 或者使用 regex.exec(str);
console.log(RegExp.lastMatch); // 输出: "foobar"
console.log(RegExp.lastParen); // 输出: "foo"
console.log(RegExp.leftContext); // 输出: ""
console.log(RegExp.rightContext); // 输出: ""
console.log(RegExp.multiline); // 输出: false
- 小总结
- test 检查指定字符串是否存在
- exec 和 match 都可以获取值,区别一个是正则表达式的方法,一个是字符串的方法
6 进阶用法
6.1 原子组
如果你要获取某个地方的东西,那就给他个(),例如这样
在 replace 中可以通过$2获取到第二个原子组((\w+))的信息
// 我希望获取到标签名以及标签内容
let str = "<h1>123</h1>";
let reg = /<(h[1-6])>(\w+)<\/h1>/;
// 将整个标签替换为标签的内容
console.log(str.replace(reg, "$2")); // 123
str.replace(reg, (p0, p1, p2) => {
// p0 = <h1>123</h1>
// p1 = h1
// p2 = 123
console.log(p0, p1, p2);
});
console.log(str.match(reg)[2]); // 123
$&: 代表自己
let str = '<a href=<123>456>789>'
main.innerHTML.replace(/替换/g. `<a href="#">已被$&</a>`)
// 页面会显示为:已被替换
- 忽略原子组:
?:
let str = "<h1>123</h1>";
let reg = /<(?:h[1-6])>(\w+)<\/h1>/;
console.log(str.match(reg)[1]); // 123
6.2 断言匹配
断言简单来说就是根据条件筛选出特点的符合条件的内容
?= /条件(?=内容)/ // 匹配出后面具有某内容的条件
?<= /(?<=内容)条件/ // 匹配出前面具有某内容的条件
?! /条件(?!内容)/ // 匹配出后面不具有某内容的条件
?<! /(?<!内容)条件/ // 匹配出前面不具有某内容的条件
?=: 匹配出后面具有某内容的条件
let str = "你知道么555啦啦啦";
const reg = /\d+(?=啦)/;
console.log(reg.exec(str)); // 555
?<=: 匹配出前面具有某内容的条件
// 前面第一个字是关键字 "么" ,那么返回这段数字
let str = "你知道么555啦啦啦";
const reg = /(?<=么)\d+/;
console.log(reg.exec(str)); // 555
6.3 其他
- 禁止贪婪
?- 第一次匹配成功,就不再往后匹配了
let str = "<a href=<123>456>789>";
console.log(str.match(/<a href=<(.*)>/)); // 123>456>789
console.log(str.match(/<a href=<(.*?)>/)); // 123
- 命名捕获
?<关键字>,使用$<关键字>捕获
const reg = /<h1>(?<text>.*)<\/h2>/;
let str = "<h1>baidu</h1>";
console.log(str.replace(reg, "<h2>$<text></h2>")); // <h1>baidu</h1>
7 案例
- 限定用户名输入的长度只能是 6-10 位字母,数字,下划线
// 限定用户名输入的长度只能是6-10位字母,数字,下划线
let reg = /^[a-z0-9_]{6,10}$/i;- 驼峰格式替换
// 驼峰格式替换
let str = "get-element-by-id";
let reg = /-\w/g;
str = str.replace(reg, (res) => {
return res[1].toUpperCase();
});
console.log(str); // getElementById
- 满足 xxxx-xx-xx 或者 xxxx/xx/xx 的都符合日期格式要求
// 满足xxxx-xx-xx或者xxxx/xx/xx的都符合日期格式要求
let date1 = "2021/04/01";
let date2 = "2021-04-01";
let reg = /^\d{4}([-/])\d{2}\1\d{2}$/;
console.log(reg.test(date1)); // true
console.log(reg.test(date2)); // true
- 对下面三个链接进行替换,把不是 https 的替换成 https,没有 www 的添加 www
// 对下面三个链接进行替换,把不是https的替换成https,没有www的添加www
let a1 = "http://www.baidu.com";
let a2 = "http://www.taobao.com";
let a3 = "https://jd.com";
let arr = [a1, a2, a3];
let reg = /(https?)(:\/\/)(www.)?(.*)/gi;
let res = arr.map((item) => {
return item.replace(reg, (...args) => {
args[1] = args[1] === "http" ? "https" : args[1];
args[3] = args[3] || "www.";
return args.splice(1, 4).join("");
});
});
console.log(res); // ["https://www.baidu.com", "https://www.taobao.com", "https://www.jd.com"]
- 把下面的 h1,h2 标签替换成 p 标签
// 把下面的h1,h2标签替换成p标签
let dom = `
<h1>ychizzz</h1>
<span>chizzz</span>
<h2>YCHIZZZ</h2>
`;
let reg = /<(h[1-6])>([\s\S]+)<\/\1>/gi;
// 此处的args从第1项开始代表了每个组,因为正则里表示内容的组([\s\S])是第二个,因此取args[2]
dom.replace(reg, (...args) => `<p>args[2]</p>`);- 密码验证,大小写字母
input.addEventListener("keyup", (e) => {
const value = e.target.value;
let r = [/^[a-z]{5,10}$/i, /[A-Z]/, /[0-9]]/];
let state = r.every((e) => e.test(value));
console.log(state ? "yes" : "no");
});- 只获取中文
let str = "你好世界! Hello World 你好";
let reg = /[^\w\!\s]+/g;
let reg2 = /\p{sc=Han}+/gu;
console.log(str.match(reg2)); // [ '你好世界', '你好' ]