let url = `http://www.wuhuepb.gov.cn/WebFileDb/NewFile/201407010837081010.pdf`;
let name = "";
if (/.*\/(.+)\.pdf$/.test(href)) {
name = url.match(/.*\/(.+)\.pdf$/)[1];
}
console.log(name); // 201407010837081010
提取标签属性
// 匹配 id
// 1
let regex = /id=".*?"/; // 想想为什么要加? 不加的话 连后面的class都会匹配到
let string = '<div id="container" class="main"></div>';
console.log(string.match(regex)[0]);
// 2
let regex = /id="[^"]*"/;
let string = '<div id="container" class="main"></div>';
console.log(string.match(regex)[0]);
提取颜色
找出形如 #abc 或 abcdef 的颜色值。即 #后面跟着 3 个或 6 个十六进制的数字。
let regexp = /#([a-f0-9]{3}){1,2}\b/gi;
let str = "color: #3f3; background-color: #AA00ef; and: #abcd";
alert(str.match(regexp)); // #3f3 #AA00ef
// (\d+(?:\.\d+)?)\s*([\+\-\*\/])\s*(\d+(?:\.\d+)?)
function parse(expr) {
let regexp = /(-?\d+(?:\.\d+)?)\s*([-+*\/])\s*(-?\d+(?:\.\d+)?)/;
let result = expr.match(regexp);
if (!result) return [];
result.shift();
return result;
}
alert(parse("-1.23 * 3.45")); // -1.23, *, 3.45
匹配位置
语法例子
\b \B
\d \D
\s \S
// 开始与结束
'I love Rainbow.'.replace(/^/,'❤️'); // ❤️I love Rainbow.
'I love Rainbow.'.replace(/$/,'❤️'); // I love Rainbow.❤️
// \b 单词的边界
'I love Rainbow.'.replace(/\b/,'❤️'); // ❤️I❤️ ❤️love❤️ ❤️Rainbow❤️.
// \B 非单词的边界
'I love Rainbow.'.replace(/\B/,'❤️'); // I l❤️o❤️v❤️e R❤️a❤️i❤️n❤️b❤️o❤️w.❤️
// (?:p) 和直接匹配 p 差不多,表示非捕获组
'I love Rainbow.'.replace(/(?:R)/,'❤️'); // I love ❤️ainbow.
x(?=y) 前瞻肯定断言 x 被 y 跟随时匹配 x
x(?!y) 前瞻否定断言 x ,仅当后面不跟 y
(?<=y)x 后瞻肯定断言 x ,仅当跟在 y 后面
(?<!y)x 后瞻否定断言 x ,仅当不跟在 y 后面
// (?=p) 符合p子模式前面的那个位置 (正向先行断言)
'I love Rainbow.'.replace(/(?=R)/,'❤️'); // I love ❤️Rainbow.
// (?!p) 符合非p子模式前面的那个位置 (负向先行断言)
'I love Rainbow.'.replace(/(!R)/,'❤️'); // ❤️I❤️ ❤️l❤️o❤️v❤️e❤️ R❤️a❤️i❤️n❤️b❤️o❤️w❤️.❤️
// (?<=p) 符合p子模式后面(注意(?=p)表示的是前面)的那个位置
'I love Rainbow.'.replace(/(<=R)/,'❤️'); // I love R❤️ainbow.
// (?<=p)反过来的意思,可以理解为(?<=p)匹配到的位置之外的位置都是属于(?<!p)的
'I love Rainbow.'.replace(/(<!R)/,'❤️'); // ❤️I❤️ ❤️l❤️o❤️v❤️e❤️ ❤️Ra❤️i❤️n❤️b❤️o❤️w❤️.❤️
// 单词间隔换为 ❤️,实现类似 \s
"I love Rainbow.".replace(/(?!\.)\W/, "❤️"); // I❤️love❤️Rainbow.
数字的千分位分割法
自后向前
let price = "123456789";
let priceReg = /(?!^)(?=(\d{3})+$)/g;
console.log(price.replace(priceReg, ",")); // 123,456,789
/(\d{3})/+$/ //自后向前必须是1个或多个的3个连续数字;
/(?!^)/+$/ // 这个位置不在首位 (用 \B 也是可以的)
自前向后匹配
let price = "123456789";
let priceReg = /\B(?=(\d{3})+(?!\d))/g;
console.log(price.replace(priceReg, ",")); // 123,456,789
/\B(?=(\d{3})+)/ // 不在开头和结尾,自前向后必须是跟着1个或多个的3个连续数字的位置;
/(?!\d)/ // 这个位置后面不允许跟着数字;
手机号 3-4-4 分割
将手机号 13112345678 转化为 131-1234-5678
let mobile = "13112345678";
let mobileReg = /(?=(\d{4})+$)/g;
console.log(mobile.replace(mobileReg, "-")); // 131-1234-5678
综合案例
提取 img 信息
const tabContent = `<p style="text-align: center;"><img href="{"app":"https://a.cn/qwcrm/dl//fyiYVr","miniProgram":"https://a.cn/qwcrm/h5/#/codScanning?corp_id=wwe072c386cba35e96&channelId=367412"}" src="https://a.cn/xxxcms/file/upload/mob/productImg/S20200276/banenr@3x.png"/></a></p><p style="text-align: center;"><img src="https://a.cn/xxxcms/ueditor/20220209/a96f4da8-f448-4862-8a2e-546759f85389.png" title="02@2x.png" _src="https://a.cn/xxxcms/ueditor/20220209/a96f4da8-f448-4862-8a2e-546759f85389.png" alt="02@2x.png"/></p></p>`;
/**
* 解析image标签
* @param {String} html 待解析的html文本
*/
function parseImage(html) {
let result = [];
//匹配图片
imageArray = html.match(/<img.*?(?:>|\/>)/gi);
result = imageArray
.map((str) => {
let src,
link = "";
//匹配链接
let srcReg = /src=(['"])?([^'"]*)\1?/i;
//匹配跳转链接
let hrefReg = /href=(['"])?([^'"]*)\1?/i;
let hrefReg__obj = /href=(['"])({.*})\1/i;
let srcMatching = str.match(srcReg) || [];
let hrefMatching1 = str.match(hrefReg) || [];
let hrefMatching2 = str.match(hrefReg__obj) || [];
src = srcMatching[2];
link = hrefMatching2[2] || hrefMatching1[2] || "";
return src ? { src, link } : false;
})
.filter((item) => {
//过滤掉无资源链接图片
return item;
});
return result;
}
console.log(parseImage(tabContent));
// [
// {
// src: "https://a.cn/xxxcms/file/upload/mob/productImg/S20200276/banenr@3x.png",
// link: '{"app":"https://a.cn/qwcrm/dl//fyiYVr","miniProgram":"https://a.cn/qwcrm/h5/#/codScanning?corp_id=wwe072c386cba35e96&channelId=367412"}',
// },
// {
// src: "https://a.cn/xxxcms/ueditor/20220209/a96f4da8-f448-4862-8a2e-546759f85389.png",
// link: "",
// },
// ];
提取 table 内容
let trimHtml = table.replace(/\s{2,}/g, "");
const matchs = [...trimHtml.matchAll(/<td.*?>(.*?)<\/td>/g)];
const result = matchs
.map((v) => {
return (v && v[1]) || "";
})
.join("");
console.log(result);
var str = "Hei, my name is <%name%>, and I'm <%info.age%> years old. I like <%info.likes[0].name%>.";
var obj = {
name: "yanyue404",
info: {
age: "20",
likes: [
{
id: 1,
name: "basketball",
},
],
},
};
alert(tplEngine(str, obj)); // Hei, my name is yanyue404, and I'm 20 years old. I like basketball.
var tpl =
"<% for(var i = 0; i < posts.length; i++) {" +
"var post = posts[i]; %>" +
"<% if(!post.expert){ %>" +
"<span>post is null</span>" +
"<% } else { %>" +
'<a href="#"><% post.expert %> at <% post.time %></a>' +
"<% } %>" +
"<% } %>";
var data = {
posts: [
{
expert: "content 1",
time: "yesterday",
},
{
expert: "content 2",
time: "today",
},
{
expert: "content 3",
time: "tomorrow",
},
{
expert: "",
time: "eee",
},
],
};
console.log(tplEngine(tpl, data));
// <a href="#">content 1 at yesterday</a>
// <a href="#">content 2 at today</a>
// <a href="#">content 3 at tomorrow</a>
// <span>post is null</span>
前言
记录正则实际使用案例,举一反三。
搭配在线工具
匹配字符
校验
网络接口的 MAC 地址 由 6 个以冒号分隔的两位十六进制数字组成。
例如:'01:32:54:67:89:AB'。
编写一个检查字符串是否为 MAC 地址的正则表达式。
用例:
只要是 13,14,15,16,17,18,19 开头即可
仅允许中文、字母、数字和
•_-
2 代,18 位数字,最后一位是校验位,可能为数字或字符 X
1-1000
大于等于 0, 小于等于 150, 支持小数位出现 5, 如 145.5, 用于判断考卷分数
1-65535
提取有效信息
找出形如 #abc 或 abcdef 的颜色值。即
#
后面跟着 3 个或 6 个十六进制的数字。(1)手机号
保留前 3 位和最后 4 位,其余用*代替。
(2)姓名
3 个字以内隐藏第 1 个字,4-6 个字隐藏前 2 个字,大于 6 个字隐藏第 3-6 个字,隐藏字用*代替;
(3)身份证
号码最后四位用*替换。
编写一个正则表达式,找出所有十进制数字,包括整数、浮点数和负数。
用例:
解决方案带有可选小数部分的正数:
\d+(\.\d+)?
。 让我们在开头加上可选的 -:一个算术表达式由 2 个数字和一个它们之间的运算符组成,例如:
运算符为 "+"、"-"、"*" 或 "/" 中之一。
在开头、之间的部分或末尾可能有额外的空格。
创建一个函数
parse(expr)
,它接受一个表达式作为参数,并返回一个包含 3 个元素的数组:用例:
匹配位置
语法例子
数字的千分位分割法
自后向前
自前向后匹配
手机号 3-4-4 分割
将手机号 13112345678 转化为 131-1234-5678
综合案例
提取 img 信息
提取 table 内容
实现一个模板引擎
测试例子:
参考链接