正则表达式初体验

1.基本语法

.除换行外任何字符 优先级较高 作用一

\.普通点 转义后 作用二

\d数字 0~9

 \s空白 \S除了空白 []元子表中加入^非 匹配非元子表中的其他内容 

let price = '23.23';
let price1 = 2323; 
console.log('验证点的作用一', /\d+.\d+/.test(price1)); // 输出 true .除换行外任何字符
console.log('验证点的作用二', /\d+\.\d+/.test(price)); // 输出true
let regDots = new RegExp('\\d+\\.\\d+'); // 这么写的原因是 '\d+\.+\d+'会被转义为d+.d+ 所以为了达到效果 转义\需要在表达式里再加一层
let url = 'https://www.baidu.com';
console.log('校验网址', /https?:\/\/\w+\.\w+\.\w+/.test(url));
let hd = "张三:010-99999999,李四:020-88888888";
console.log('输出匹配到一组手机号', hd.match(/\d{3}-\d{7,8}/)); // \d数字 \D非数字 输出 ["010-99999999"]
console.log('输出匹配出所有手机号', hd.match(/\d{3}-\d{7,8}/g)); // 输出 ["010-99999999", "020-88888888"]
console.log('匹配非数字', hd.match(/\D+/g)); // 输出 ["张三:", "-", ",李四:", "-"]
console.log('匹配数字等特殊字符', hd.match(/[-\d:,]/g)); // 输出 ["0", "1", "0", "-", "9", "9", "9", "9", "9", "9", "9", "9", "0", "2", "0", "-", "8", "8", "8", "8", "8", "8", "8", "8"]
console.log('匹配数字等特殊字符', hd.match(/[-\d:,]+/g)); // 输出 ["010-99999999", "020-88888888"]
console.log('匹配非数字等特殊字符', hd.match(/[^-\d:,]+/g)); // 输出["张三:", ",李四:"]

\w 字母数字下划线(不包括中划线和特殊字符) \W 除了数字字母下划线

let email = "1974931363@qq.com";
console.log('匹配简单邮箱', email.match(/^\w+@\w+\.\w+$/g)); // 输出 ["1974931363@qq.com"]
console.log('匹配除了数字字母下划线的内容', "hsjdsde@".match(/\W/)); // 输出 ["@"]
// 匹配字母开始 5-10位前缀的邮箱
console.log('匹配字母开始 5-10位前缀的邮箱', 'a197493136@qq.com'.match(/^[a-z]\w{4,9}@\w{2,3}\.\w{2,3}$/g)); // 输出["a197493136@qq.com"]
// 匹配带空格的座机号 
let telReg = "010 - 99999999";
console.log('匹配带空格的座机号方法一', telReg.match(/^\d+\s-\s\d{8}$/)); // 直接输入空格和\s都可匹配到 ["010 - 99999999"]
console.log('匹配带空格的座机号方法二', telReg.match(/^\d+ - \d{8}$/)); // 输出 ["010 - 99999999"]
// 匹配所有字符 [\s\S] [\d\D] [\w\W]
console.log('匹配所有字符', "shwjewue@@#sd".match(/[\w\W]+/)); // 输出 ["shwjewue@@#sd"]
// 匹配座机是北京或者上海

let regPhone = /^(010|020)\-\d{7,8}$/;

let phoneNum = '020-9999999';

console.log('检查手机号是否是北京或者上海', regPhone.test(phoneNum)); // true
// 模式修正符 i g
let hdTest = "hsdusUjshds";
console.log('全局匹配大小写u', hdTest.match(/u/ig)); // 输出 ["u", "U"]
console.log('全局匹配大小写u并替换成@', hdTest.replace(/u/ig, '@')); // 输出 hsd@s@jshds
// 匹配多行
let testMultiple = `
#1 js,200元 #
#2 php,300元 #
#9 xiaowenge # test
#3 node.js,180元 #
`
console.log('匹配多行',testMultiple.match(/^\s*#\d+\s+.+\s+#$/gm)); // 输出 ["\n        #1 js,200元 #", "        #2 php,300元 #", "        #3 node.js,180元 #"]
// 将多行内容 匹配出来 并且去除#相关数据 只留中间名字和价格 输出
let resultsMultiple = testMultiple.match(/^\s*#\d+\s+.+\s+#$/gm).map(v => {
    v = v.replace(/\s*#\d+\s*/, '').replace(/\s+#/, '');
    [name, price] = v.split(',');
    return {name, price};
})
console.log('resultsMultiple', JSON.stringify(resultsMultiple, null, 2)); // 输出 resultsMultiple 如下 2是缩进2个字符
`[
    {
        "name": "js",
        "price": "200元"
    },
    {
        "name": "php",
        "price": "300元"
    },
    {
        "name": "node.js",
        "price": "180元"
    }
]`
// 汉字与字符属性 \p{L}匹配所有字符不包含数字 \p{P}匹配所有字符标点等 \p{N} 所有数字 \P{L} 不是字母,等价于 [^\p{L}] \P{N} 不是数字,等价于 [^\p{N}] [\p{N}\p{L}] 所有数字和所有字母,类似于 \w 
let testHdReg = "hjwewuyew2021.不断手机端还是等会,加油!"
console.log('匹配所有内容', testHdReg.match(/\p{L}/gu)); // 输出 ["h", "j", "w", "e", "w", "u", "y", "e", "w", "不", "断", "手", "机", "端", "还", "是", "等", "会", "加", "油"]
console.log('匹配所有字符', testHdReg.match(/\p{P}/gu)); // 输出 [".", ",", "!"]
console.log('匹配所有中文字符', testHdReg.match(/\p{sc=Han}/gu)); // 匹配所有汉字 ["不", "断", "手", "机", "端", "还", "是", "等", "会", "加", "油"]
// lastIndex属性的作用
let testData = 'lee.shou';
console.log('检索字符串', testData.match(/\w/g)); // 输出 ["l", "e", "e", "s", "h", "o", "u"]
let regLast = /\w/g; // 全局匹配 如果正则是/\w/ 没有g 非全局匹配 那么 下面检索匹配内容输出的都是["l", index:0, input: "lee.shou", groups: undefined] regLast.lastIndex输出的都是0
console.log('检索匹配内容', regLast.exec(testData)); // 输出["l", index:0, input: "lee.shou", groups: undefined]
console.log('regLast.lastIndex :>> ', regLast.lastIndex); // 输出 1
console.log('检索匹配内容', regLast.exec(testData)); // 输出["e", index:1, input: "lee.shou", groups: undefined]
console.log('regLast.lastIndex :>> ', regLast.lastIndex); // 输出 2
while (res = regLast.exec(testData)) {
    console.log('分别循环每一个数组内容 :>> ', res);
    // 输出分别循环每一个数组内容 :>>  ["e", index: 2, input: "lee.shou", groups: undefined]
    // ["s", index: 4, input: "lee.shou", groups: undefined]
    // ["h", index: 5, input: "lee.shou", groups: undefined]
    // ["o", index: 6, input: "lee.shou", groups: undefined]
    // ["u", index: 7, input: "lee.shou", groups: undefined] 前面输出过的就不再输出了
}
// 有效率的y模式 y和g模式对比 y模式连续查找 不会跳过 如果下一个连续的字符串不满足条件就回返回空 lastIndex 重新变为0 g模式可以跳过查找符合条件的内容 一直查到结尾 
let testG = /u/g;
let testYstring = 'uggugg';
console.log('查找数据 :>> ', testG.exec(testYstring)); // ["u", index: 0, input: "uggugg", groups: undefined]
console.log('查找位置 :>> ', testG.lastIndex); // 1
console.log('查找数据 :>> ', testG.exec(testYstring)); // ["u", index: 3, input: "uggugg", groups: undefined]
console.log('查找位置 :>> ', testG.lastIndex); // 4

let testY = /u/y;
console.log('查找数据 :>> ', testY.exec(testYstring)); // ["u", index: 0, input: "uggugg", groups: undefined]
console.log('查找位置 :>> ', testY.lastIndex); // 1
console.log('查找数据 :>> ', testY.exec(testYstring)); // null
console.log('查找位置 :>> ', testY.lastIndex); // 0

// y模式应用场景
let testYdata = '这几个人的QQ号分别是:1974512535,157420,8542124请录入';
let regYdata = /(\d+),?/y; // ?是0个或1个 
regYdata.lastIndex = 12;
console.log('匹配QQ号 :>> ', regYdata.exec(testYdata)); // ["1974512535,", "1974512535", index: 12, input: "这几个人的QQ号分别是:1974512535,157420,8542124请录入", groups: undefined]
console.log('匹配QQ号 :>> ', regYdata.exec(testYdata)); // ["157420,", "157420", index: 23, input: "这几个人的QQ号分别是:1974512535,157420,8542124请录入", groups: undefined]
console.log('匹配QQ号 :>> ', regYdata.exec(testYdata)); // ["8542124", "8542124", index: 30, input: "这几个人的QQ号分别是:1974512535,157420,8542124请录入", groups: undefined]
// 原子表 匹配日期
let testDate = '2022-02-23';
let testDateContent = '2022/02-23'
let regDate = /^\d{4}[-\/]\d{2}[-\/]\d{2}$/;
console.log('测试匹配日期:>> ', testDate.match(regDate)); // ["2022-02-23", index: 0, input: "2022-02-23", groups: undefined] 这样匹配有问题 2022/02-23去匹配也可以输出
let regDateAccurate = /^\d{4}([-\/])\d{2}\1\d{2}$/; // 因为([-\/])使用了原子组 所以该正则表达式里的\1代表的是与前面一致的原子组
console.log('测试匹配日期精准:>> ', testDateContent.match(regDateAccurate)); // null 因为testDateContent一个/一个-不满足条件 所以返回空 如果改成 2022/02/23则正常返回 匹配到的数组
// 区间匹配
let numberInterval = '2010';
console.log('匹配数字:>> ', numberInterval.match(/\d+/g)); // 输出 ["2010"]
console.log('匹配数字:>> ', numberInterval.match(/[0-9]+/g)); // 输出 ["2010"]
let letterInterval = "testinterval";
console.log('匹配字母:>> ', letterInterval.match(/[a-z]+/g)); // 输出 ["testinterval"]
let letterAndAnother = 'A12s233few';
console.log('匹配字母开头 数字字母下划线跟进拼接数据', letterAndAnother.match(/^[a-z]\w+$/i)); // 输出 ["A12s233few", index: 0, input: "A12s233few", groups: undefined] i模式不区分大小写
// 排除匹配 []里面的内容是包含 例如[0-9] 排除是[]中加入^ 例如 [^0-9]是指除了数字0-9
let ruleoutString = 'aftermon';
console.log(' 匹配除了tm以外的其他字符:>> ', ruleoutString.match(/[^tm]/gi)); // 输出 ["a", "f", "e", "r", "o", "n"]
let keepHan = '张三:021-0927162, 李四:010-8826723';
console.log(' 只保留中文:>> ', keepHan.match(/[^\d:\-,]+/g)); // 输出 ["张三", " 李四"] +是1个或多个 g是全局匹配  [^\d:\-,]的意思是 匹配除了数字 冒号 逗号 -以外的内容 因为-是特殊字符 所以需要转义 \- 
// 原子表字符不解析 ()在正则表达式中是原子组的意思 但是在[()]中的括号 就是普通括号的意思 .+在正则表达式中是匹配1个或者多个除了换行符以外的其他字符 但是在[.+]中 .+就是原意.+
let testNotParse = '(test123).+';
console.log('原子组匹配 :>> ', testNotParse.match(/(\w)/gi)); //  ["t", "e", "s", "t", "1", "2", "3"]
console.log('原子组匹配 :>> ', testNotParse.match(/[(\w)]/gi)); // ["(", "t", "e", "s", "t", "1", "2", "3", ")"]
console.log('原子组匹配 :>> ', testNotParse.match(/.+/gi)); // ["(test123).+"]
console.log('原子组匹配 :>> ', testNotParse.match(/[.+]/gi)); // [".", "+"]
// 使用原子表匹配所有内容 [\s\S] 匹配所有内容 [\d\D] 匹配所有内容

let testAllContent = `
#1 js,200元 #
#2 php,300元 #
#9 xiaowenge # test
#3 node.js,180元 #
`
console.log(' 测试:>> ', testAllContent.match(/.+/gs)); // 与下面两者等价 s模式是忽略换行符 .+到换行符处就不匹配了 加上s模式就可以将整个内容都匹配出来 输出 ["\n        #1 js,200元 #\n        #2 php,300元 #\n      …aowenge # test\n        #3 node.js,180元 #\n        "]
console.log(' 测试:>> ', testAllContent.match(/[\s\S]+/)); // 输出 与上面两者等价 ["\n        #1 js,200元 #\n        #2 php,300元 #\n      …aowenge # test\n        #3 node.js,180元 #\n        ", index: 0, input: "\n        #1 js,200元 #\n        #2 php,300元 #\n      …aowenge # test\n        #3 node.js,180元 #\n        ", groups: undefined]
console.log(' 测试:>> ', testAllContent.match(/[\s\S]+/)[0]); // 输出如下 testAllContent原本格式内容
// #1 js,200元 #
// #2 php,300元 #
// #9 xiaowenge # test
// #3 node.js,180元 #
// 正则操作Dom元素 Dom元素内容script外面的body内
<body>
    <div>正则操作Dom元素</div>
    <h1>testh1的数据</h1>
    <h2>h2相关的内容</h2>
    <h3></h3>
    <h4>
        testh4
        test
    </h4>
</body>
let getBody = document.body;
let regReplace = /<(h[1-6])>[\s\S]*<\/\1>$/gim;
console.log('替换:>> ', '<h1>test</h1>'.match(regReplace)); // 输出 ["<h1>test</h1>"]
let matchBody = getBody.innerHTML.match(regReplace);
console.log('matchBody :>> ', matchBody); // ["<h1>testh1的数据</h1>\n    <h2>h2相关的内容</h2>\n    <h3></h3>\n    <h4>\n        testh4\n </h4>"]
getBody.innerHTML = getBody.innerHTML.replace(regReplace, "");
// 认识原子组
let testGroups = /<(h[1-6])>[\s\S]*<\/\1>/i;
let testGroupString = `
<h1>testdata</h1> <h2>testhhh2</h2>`;
console.log('认识原子组 :>> ', testGroupString.match(testGroups)); // ["<h1>testdata</h1>", "h1", index: 9, input: "\n        <h1>testdata</h1> <h2>testhhh2</h2>", groups: undefined]
// 邮箱验证中原子组的使用
let mailData = "15445479@sina.com.cn";
let mailQQ = "1014758151@qq.com";
let mailReg = /^[\w-]+@([\w-]+\.)+(com|cn|org|cc|net)$/gi;
console.log('邮箱验证中原子组的使用 :>> ', mailData.match(mailReg)); // ["15445479@sina.com.cn"]
console.log('邮箱验证中原子组的使用QQ邮箱 :>> ', mailQQ.match(mailReg)); // ["1014758151@qq.com"]
// 原子组引用 完成替换操作
let testReplaceReg = /<(h[1-6])>([\s\S]*)<\/\1>/gi;
let testReplaceLable = `
    <h1>testh1</h1>
    <span>testspan</span>
    <h2>testh2</h2>
    `;
console.log('替换h1为p标签 :>> ', testReplaceLable.replace(testReplaceReg, `<p>$2</p>`)); // 输出 
//    <p>testh1</p>
//    <span>testspan</span>
//    <p>testh2</p>
let replaceFunction = testReplaceLable.replace(testReplaceReg, (p0, p1, p2) => {
    // p0 <h1>testh1</h1> <h2>testh2</h2>
    // p1  h1 h2
    // p2 testh1 testh2
    return `<p>${p2}</p>`
});
console.log('replaceFunction', replaceFunction); // 输出的值同上
// 嵌套分组与不记录组 ?:标注的内容 不计入原子组 此时 $1 \1将失效 $2 \2将失效
let testNotRecord = /https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|org))/gi;
let testNotRecordString = `
https://www.baidu.com
https://dior.cn
http://taobao.com
`;

console.log(' 嵌套分组与不记录组:>> ', testNotRecordString.match(testNotRecord)); // ["https://www.baidu.com", "https://dior.cn", "http://taobao.com"]
let collectionUrl = [];
while (result = testNotRecord.exec(testNotRecordString)) {
    console.log('result', result);
    collectionUrl.push(result[0]);
}
console.log('collectionUrl', collectionUrl); // ["https://www.baidu.com", "https://dior.cn", "http://taobao.com"] 注意不能在while外层提前打印执行testNotRecord.exec(testNotRecordString)看是否生效以及输出的值 如此操作的话 会改变lastIndex while中就会少匹配到第一个内容 从第二个开始了
// 多种重复匹配基本使用 * 0个或多个 + 1个或多个 ? 0个或1个 贪婪模式 {2,5}匹配2个到5个 如果有5个 会找到5个 {3}匹配3个 {1,}匹配1个到无穷多个
let testHd = "hdddddd";
console.log('匹配0个或多个 :>> ', testHd.match(/hd*/g)); // ["hdddddd"]
console.log('匹配1个或多个 :>> ', testHd.match(/hd+/g)); // ["hdddddd"]
console.log('匹配0个或1个 :>> ', testHd.match(/hd?/g)); // ["hd"]
console.log('匹配2个到5个 :>> ', testHd.match(/hd{2,5}/g)); // ["hddddd"]
console.log('匹配3个 :>> ', testHd.match(/hd{3}/g)); // ["hddd"]
console.log('匹配1个到无穷多个 :>> ', testHd.match(/hd{1,}/g)); // ["hdddddd"]
// 重复匹配对原子组影响与电话号正则
let testGroundAdd = "hddddhdhdhdhdd"
console.log(' 匹配所有hd:>> ', testGroundAdd.match(/(hd)+/g)); // ["hd", "hdhdhdhd"]
let telFourAreaCode = '0478-66723527';
let telThreeAreaCode = '010-9999999';
let regAllPhone = /^0\d{2,3}-\d{7,8}$/g
console.log('匹配区号为四位的电话号 :>> ', telFourAreaCode.match(regAllPhone)); // ["0478-66723527"]
console.log('匹配区号为三位的电话号 :>> ', telThreeAreaCode.match(regAllPhone)); // ["010-9999999"]
// 网站用户名验证 a-z开头 全长最多8位 后7位可以是-或者数字字母下划线
<div>
    验证用户名:<input type="text" id="userName" />
</div>
console.log('document.getElementById(test :>> ', document.getElementById("userName"));
document.getElementById("userName").addEventListener("keyup", e => {
    const value = e.target.value;
    let testUserName = /^[a-z][\w-]{2,7}$/i;
    console.log('校验用户名是否符合 :>> ', testUserName.test(value)); // 输入a12 true a12323212 false 超位数 11111 false
})
// 批量使用正则完成密码验证 密码包含字母数字 并且必须包含1个大写的字母 为了方便操作 这里input写的text类型
<div>
    验证密码:<input type="text" name="password">
</div>
document.querySelector(`[name="password"]`).addEventListener('keyup', e => {
    const value = e.target.value;
    const testPassword = [
        /^[a-z0-9]{5,10}$/i, /[A-Z]/, /[0-9]/
    ]
    let correctResults = testPassword.every(eve => eve.test(value));
    console.log('验证密码是否正确 :>> ', correctResults); // 当输入数字 大写字母并且位数大于等于5小于等于10的时候 返回true 小写字母这里是可选的 所以不影响结果 输入位数不足 或者没满足条件时 返回false
})
// 禁止贪婪 ?
let testBan = 'hddddddd';
console.log(' 禁止贪婪1个或多个:>> ', testBan.match(/hd+?/g)); // ["hd"]
console.log(' 禁止贪婪0个或多个:>> ', testBan.match(/hd*?/g)); // ["h"]
console.log(' 禁止贪婪0个或1个:>> ', testBan.match(/hd??/g)); // ["h"]
console.log(' 禁止贪婪区间数据:>> ', testBan.match(/hd{2,5}?/g)); // ["hdd"]
console.log(' 禁止贪婪区间无穷大数据:>> ', testBan.match(/hd{3,}?/g)); // ["hddd"]
// 标签替换的禁止贪婪使用
<main id="spanChange">
    <span>testchange</span>
    <span>changespan</span>
    <span>mychange</span>
</main>
const changeSpan = document.querySelector("#spanChange")
const changeSpanReg = /<span>([\s\S]+?)<\/span>/gi;
console.log(' 数据转换:>> ', changeSpan.innerHTML.match(changeSpanReg));
changeSpan.innerHTML = changeSpan.innerHTML.replace(changeSpanReg, (v, p1) => {
    return `<h4 style="color: red;">h4替换内容-${p1}</h4>` // 输出结果为红色的 内容如下
    // h4替换内容-testchange
    // h4替换内容-changespan
    // h4替换内容-mychange
})
// 使用matchAll完成全局匹配
<main id="matchAll">
    <h1>匹配内容h1</h1>
    <h2>匹配内容h2</h2>
    <h1>匹配内容h1</h1>
</main>
const matchAllData = document.querySelector("#matchAll");
const matchAllReg = /<(h[1-6])>([\s\S]+?)<\/\1>/gi;
const allMatchData = matchAllData.innerHTML.matchAll(matchAllReg);
console.log('匹配所有 :>> ', matchAllData.innerHTML.matchAll(matchAllReg));
let contents = [];
for (const iterator of allMatchData) {
    console.dir(iterator); // iterator为数组 ["<h1>匹配内容h1</h1>", "h1", "匹配内容h1", groups: undefined, index: 9, input: "\n        <h1>匹配内容h1</h1>\n        <h2>匹配内容h2</h2>\n        <h1>匹配内容h1</h1>\n"]
    contents.push(iterator[2]); // iterator[2] 分别是匹配内容h1 匹配内容h2 匹配内容h1
}
console.table(contents); // 控制台表格输出 h1 h2里面的内容

// 为低端浏览器定义原型方法 matchAll
String.prototype.matchAll = function (reg) {
    let res = this.match(reg);
    console.log('res :>> ', res);
    if (res) {
        let str = this.replace(res[0], '^'.repeat(res[0].length));
        let match = str.matchAll(reg) || [];
        console.log('match', match);
        return [res, ...match];
    }
}
let testMatchAll = 'hyetgegghgeeh';
console.log('为低端浏览器定义原型方法 matchAll :>> ', testMatchAll.matchAll(/h/i)); // 返回 [["h", index: 0, input: "hyetgegghgeeh", groups: undefined],["h", index: 8, input: "^yetgegghgeeh", groups: undefined], ["h", index: 12, input: "^yetgegg^geeh", groups: undefined]]
// 正则表达式中添加变量 用构造函数表达式加入变量 字面量形式不生效
let addVariable = 3;
let getVariable = new RegExp(`${addVariable}`, 'g').exec('123');
console.log('getVariable :>> ', getVariable); // ["3", index: 2, input: "123", groups: undefined]
// 使用exec完成全局匹配
let testExecGlobal = /u/gi;
let testString = 'hwusgdguqwd';
let saveResult = [];
while (res = testExecGlobal.exec(testString)) {
    saveResult.push(res);
}
console.log('saveResult :>> ', saveResult); // [["u", groups: undefined, index: 2, input: "hwusgdguqwd"],["u", groups: undefined, index: 7, input: "hwusgdguqwd"]]

function search(string, reg) {
    let serachResult = [];
    while (res = reg.exec(string)) {
        serachResult.push(res);
    }
    return serachResult;
}
console.log(' 使用exec完成全局匹配:>> ', search('hweurtesfr', /e/gi)); // [["e", index: 2, input: "hweurtesfr", groups: undefined], ["e", index: 6, input: "hweurtesfr", groups: undefined]]
// 字符串正则方法search与match
let testSearchReg = 'huwvbsdhwy'.search(/h/); // 0
console.log('testSearchReg :>> ', testSearchReg);
let testSearchString = 'huwvbsdhwy'.search('h');
console.log('testSearchString :>> ', testSearchString); // 0
let testMatch = 'huwvbsdhwy'.match(/h/gi);
console.log('testMatch :>> ', testMatch); // ["h", "h"]
let testUrl = `
https://www.sina.com.cn
http://leeosi.com
https://www.baidu.com
`;
let regUrl = /https?:\/\/(\w+\.)?(\w+\.)+(com|cn|org|cc)/gi;
console.log('testUrl.match(regUrl) :>> ', testUrl.match(regUrl)); //  ["https://www.sina.com.cn", "http://leeosi.com", "https://www.baidu.com"]
// 字符串正则方法matchAll与split
let testUrlAll = `
https://www.sina.com.cn
http://leeosi.com
https://www.baidu.com
`;
let regUrlAll = /https?:\/\/(?:\w+\.)?(?:\w+\.)+(?:com|cn|org|cc)/gi;
console.dir(testUrlAll.matchAll(regUrlAll)); // RegExpStringIterator
for (const iterator of testUrlAll.matchAll(regUrlAll)) {
    console.log('iterator :>> ', iterator);
}
let testSplit = '2021-08/10';
console.log('split测试 :>> ', testSplit.split(/[-/]/)); // ["2021", "08", "10"]
// $符在正则替换中的使用 $`匹配到内容的左边的内容 $'匹配到内容的右边的内容 $&当前内容
let testDateReplace = "2021/08/10";
console.log('替换/为- :>> ', testDateReplace.replace(/\//g, '-'));
let telParentheses = "(010)99999999 (020)8888888"; // 把(010)99999999 替换成 010-99999999
let telParenthesesReg = /\((\d{3,4})\)([0-9]{7,8})/g;
console.log('替换电话号 :>> ', telParentheses.replace(telParenthesesReg, "$1-$2"));
let matchString = "=优秀的人#";
let matchCurrent = matchString.replace(/优秀的人/, "$&"); // =优秀的人#
let matchLeft = matchString.replace(/优秀的人/, "$`"); // ==#
let matchRight = matchString.replace(/优秀的人/, "$'"); // =##
console.log('matchCurrent :>> ', matchCurrent); // =优秀的人#
console.log('matchLeft :>> ', matchLeft); // ==#
console.log('matchRight :>> ', matchRight); // =##
console.log('多加几个符号 :>> ', matchString.replace(/优秀的人/, "$`$`$&$'$'")); // ===优秀的人###
// $&使用 将html内容中 '学历教育-在线教育是一种快速提升自我的方案' 教育2个字加上跳转链接 
<main id="replaceHref">学历教育-在线教育是一种快速提升自我的方案</main>
const getEducation = document.querySelector('#replaceHref');
getEducation.innerHTML = getEducation.innerHTML.replace(/教育/g, "<a href='https://www.baidu.com'>$&</a>")
// 原子组在替换中的使用技巧 http://www/hdyyr.com http://baidu.com 给这2个a标签对应的链接补全 不是https的补全 没有www.的加上 其他a标签的不变 h4的内容也不变
<main id="completionHref">
    <a style="color: cornflowerblue;" href="http://www.hdyyr.com">开源中国</a>
    <a href="http://baidu.com">百度</a>
    <a href="http://yahoo.com">雅虎</a>
    <h4>http://www.yahoo.com</h4>
</main>
const completeElement = document.querySelector("#completionHref");
const completeElementReg = /(<a.* href=["'])(http)(:\/\/)(www.)?(hdyyr|baidu)/gi;
completeElement.innerHTML = completeElement.innerHTML.replace(completeElementReg, (v, ...args) => {
    // console.log('v :>> ', v);
    console.log('args :>> ', args);
    args = args.splice(0,5);
    args[1] = args[1] == 'http' ? 'https': args[1];
    args[3] = args[3] || 'www.';
    return args.join(''); // <a style="color: cornflowerblue;" href="https://www.hdyyr.com">开源中国</a> <a href="https://www.baidu.com">百度</a>
})
// 原子组别名 ?<con> 给原子组起别名为con
<main id="atomicName">
    <h1>别名h1</h1>
    <span>我是span内容</span>
    <h2>别名h2</h2>
</main>
const testAtomicName = document.querySelector("#atomicName");
const testAtomicRegular = /<(h[1-6])>(.*?)<\/\1>/gi;
testAtomicName.innerHTML = testAtomicName.innerHTML.replace(testAtomicRegular, '<h4>$2</h4>');
// 等价于上面 其中?<con>就是给当前原子组起的别名 把$2用别名替换掉了 这种起别名的情况用于正则表达式中原子组较多的情况 防止混淆
const testAtomicSpecial = /<(h[1-6])>(?<con>.*?)<\/\1>/gi;
testAtomicName.innerHTML = testAtomicName.innerHTML.replace(testAtomicSpecial, '<h4>$<con></h4>');
// 使用原子组别名优化正则 ?<link> ?<title>等这种重命名的原子组 会在groups属性中提现出来
<main id="aliasOptimization">
    <a href="https://www.taobao.com">淘宝</a>
    <a href="https://baidu.com">百度</a>
    <a href="https://www.yahoo.com/">雅虎</a>
</main>
const mainAlias = document.querySelector("#aliasOptimization");
const mainAliasReg = /<a.*?href=(["'])(?<link>.*?)\1>(?<title>.*?)<\/a>/gi;
let collectData = [];
for (const iterator of mainAlias.innerHTML.matchAll(mainAliasReg)) {
    console.log('iterator :>> ', iterator);
    collectData.push(iterator.groups);
}
console.log('collectData :>> ', collectData); // [{link: "https://www.taobao.com", title: "淘宝"}, {link: "https://baidu.com", title: "百度"}, {link: "https://www.yahoo.com/", title: "雅虎"}]
// 正则方法test
<div>
    验证邮箱:<input type="text" name="email" />
</div>
const emailDom = document.querySelector(`[name="email"]`);
emailDom.addEventListener('keyup', e=> {
    let emailValue = e.target.value;
    let emailFlag = /^[\w-]+@(\w+\.)+(com|cn|org)$/i.test(emailValue);
    console.log('emailFlag :>> ', emailFlag);
})
// 正则方法exec 注意 这里的while判断里不可以直接/军人/g.exec(execTest)这样写 会进入死循环 将正则表达式/军人/g用一个变量execReg接收 就不会有这个问题
let execTest = '我是中华人民共和国解放军军人 我宣誓 坚决服从党的领导 全新全意为人民服务 军人';
let count = 0;
const execReg = /军人/g;
while(countData = execReg.exec(execTest)) {
    count++;
}
console.log('测试军人出现次数count :>> ', count);
console.log('测试exec :>> ', /军人/g.exec(execTest)); // ["军人", index: 12, input: "我是中华人民共和国解放军军人 我宣誓 坚决服从党的领导 全新全意为人民服务 军人", groups: undefined]
console.log('测试match :>> ', execTest.match(/军人/g)); // ["军人", "军人"]
// ?=断言匹配 可以理解为条件语句 断言匹配后面是什么
<main id="assert">
    巨人真的存在吗?让我们带你揭开巨人面纱;
</main>
let testAssertions = document.querySelector("#assert");
testAssertions.innerHTML = testAssertions.innerHTML.replace(/巨人(?=面纱)/g, "<a href='https://www.baidu.com'>$&</a>"); // 巨人真的存在吗?让我们带你揭开巨人面纱; 给面纱前面的巨人 加上了链接 ?=相当于判断条件 后面有面纱的巨人 才可以满足条件被匹配
// 使用断言规范价格
let lessons = `
    js,200元,300次
    php,300.00元,100次
    node.js,180元,260次
`;
const lessonsReg = /(\d+)(.00)?(?=元)/g;
lessons = lessons.replace(lessonsReg, (v1, ...args) => {
    console.log('args :>> ', args);
    args[1] = args[1] ? args[1]: '.00';
    return args.splice(0,2).join('');
}); // 方法1
lessons = lessons.replace(lessonsReg, "$1.00") // 方法2
console.log('lessons :>> ', lessons);
// ?<=断言匹配 前面是什么
let assertFront = "hwkewww789dhcbwww";
let assertFrontReg = /(?<=www)\d+/g;
console.log('?<=断言匹配 :>> ', assertFront.match(assertFrontReg)); // ["789"]
let assertHref = `
    <a href="https://www.baidu.com">百度</a>
    <a href="https://www.yahoo.com">雅虎</a>
`
let assertHrefReg = /(?<=href=(["'])).*(?=\1)/g;
console.log('object :>> ', assertHref.match(assertHrefReg));
assertHref = assertHref.replace(assertHrefReg, 'https://www.taobao.com');
console.log('assertHref :>> ', assertHref);
// 使用断言模糊电话号
let fuzzyTel = `
    李雪 15874245812
    王博 13342147841
`;
let fuzzyTelReg = /(?<=\d{7})\d{4}/g;
fuzzyTel = fuzzyTel.replace(fuzzyTelReg, (v) => {
    return '*'.repeat(4);
})
console.log('fuzzyTel :>> ', fuzzyTel);
// ?!断言匹配 断言匹配后面不是什么
let assertSub = 'houlai2020hdm';
const subReg = /[a-z]+(?!\d+)$/g;
console.log('assertSub :>> ', assertSub.match(subReg)); // ["hdm"]
// 断言限制用户名关键词
<main id="assertNoContain">
    验证内容中不包含:<input type="text" name="assertContain">
</main>
const getContain = document.querySelector(`[name='assertContain']`);
getContain.addEventListener("keyup", function() {
    const reg = /^(?!.*世界.*).*/;
    console.log('this.value.match(reg):>> ', this.value.match(reg));
})
// ?<!断言匹配 断言匹配前面不是谁
let notNum = "hhdd987yyxxd";
let notNumReg = /^(?<!\d+)[a-z]+/g;
console.log('断言匹配前面不是谁 :>> ', notNum.match(notNumReg)); // ["hhdd"]
// 使用断言排除法统一数据
let unifiedData = `
    https://www.baidu.com/1.jpg
    https://hdd.com/2.jpg
    https://oss.yundao.com/3.jpg
    https://m.dior.cn/4.jpg
    http://www.leecode.com/5.jpg
`
const unifiedDataReg = /https?:\/\/([a-z]+)?(?<!oss)\..+?(?=\/)/g;
console.log('unifiedData :>> ', unifiedData.match(unifiedDataReg)); // ["https://www.baidu.com", "https://hdd.com", "https://m.dior.cn", "http://www.leecode.com"]
unifiedData = unifiedData.replace(unifiedDataReg, v => {
    console.log('v :>> ', v);
    return "https://oss.yundao.com"
})
console.log('unifiedData :>> ', unifiedData); // 输出如下
// https://oss.yundao.com/1.jpg
// https://oss.yundao.com/2.jpg
// https://oss.yundao.com/3.jpg
// https://oss.yundao.com/4.jpg
// https://oss.yundao.com/5.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值