JS基础3-正则表达式

323 阅读6分钟

正则表达式

后盾人-基础知识

例子

    let hd = 'afdfsdfsd123dfd4567';
    // let num = [...hd].filter(item => !Number.isNaN(parseInt(item)))
    // console.log(num.join(''));
    console.log(hd.match(/\d/g).join(''));

字面量创建正则表达式

字面量无法操作变量,使用eval较为复杂

    let hd = 'houdunren.com'
    let a = 'u'
    // console.log(/u/.test(hd)); // true
    // console.log(/a/.test(hd)); // false 
    console.log(eval(`/${a}/`).test(hd)) // true

使用对象创建正则表达式

    let hd = 'houdunren.com'
    let a = 'u'
    let reg = new RegExp(a, 'g')
    console.log(reg.test(hd)); // true
    <div class="content">houdunren.com</div>
  <script>
    let div = document.querySelector('.content')
    div.innerHTML =  div.innerHTML.replace(/\w/g, search => {
      return `<sapn style='color: red;'>${search}</span>`
    })
  </script>

image.png

选择符的使用

|

        // | 选择符,选择符左右两侧整个内容
        console.log(/vu|&/.test(hd)); // true
        let tel = '010'
        let tel1 = '020'
        let tel2 = '020-9999999'
        let tel3 = '010-9999999'
        console.log(/010|020\-\d{7,8}/.test(tel)); // true
        console.log(/010|020\-\d{7,8}/.test(tel1)); // false
        console.log(/010|020\-\d{7,8}/.test(tel2)); // true
        console.log(/010|020\-\d{7,8}/.test(tel3)); // true
        console.log(/(010|020)\-\d{7,8}/.test(tel2)); // true
        console.log(/^(010|020)\-\d{7,8}$/.test(tel2)); // false ^****$完全匹配

^****$完全匹配

字符转义

转义用于改变字符的含义,用来对某个字符有多种语义时的处理。

假如有这样的场景,如果我们想通过正则查找/符号,但是 /在正则中有特殊的意义。如果写成///这会造成解析错误,所以要使用转义语法/\//来匹配。

        let num = 12.34
        console.log(/\d+\.\d/.test(num)); // true
        let reg = new RegExp('\d\.\d', 'g')
        let reg1 = new RegExp('\\d\.\\d', 'g')
        console.log(reg.test(num)); // false
        console.log(reg1.test(num)); // true

字符边界

使用字符边界符用于控制匹配内容的开始与结束约定。

边界符说明
^匹配字符串的开始
$匹配字符串的结束,忽略换行符
    // 字符边界
        let str = 'asfsdf3fgreg'
        console.log(/^\d/.test(str));
        console.log(str.match(/[a-z]{1,2}/))
        let str1 = str.match(/[a-z]{1,2}/)
        console.log(str1);

元字符

元子字符

元字符是正则表达式中的最小元素,只代表单一(一个)字符

字符列表

元字符说明示例
\d匹配任意一个数字[0-9]
\D与除了数字以外的任何一个字符匹配[^0-9]
\w与任意一个英文字母,数字或下划线匹配[a-zA-Z_]
\W除了字母,数字或下划线外与任何字符匹配[^a-zA-Z_]
\s任意一个空白字符匹配,如空格,制表符\t,换行符\n[\n\f\r\t\v]
\S除了空白符外任意一个字符匹配[^\n\f\r\t\v]
.匹配除换行符外的任意字符
       let str = 'houdunren 2010'
        /**
            /d 匹配任意一个数字
        */
        console.log(str.match(/\d/));
        console.log(str.match(/\d/g));
        console.log(str.match(/\d+/g));
        console.log('---------------------------');
        /**
            /D 与除了数字以外的任何一个字符匹配
        */
        console.log(str.match(/\D/));
        console.log(str.match(/\D/g));
        console.log(str.match(/\D+/g));
        console.log('---------------------------');
        // 数值和空白元字符
        let hd = `
            张三: 010-99999999,李四: 020-88888888
        `
        console.log(hd.match(/\d{3}-\d{7,8}/));
        console.log(hd.match(/\d{3}-\d{7,8}/g));
        console.log('---------------------------');
        /**
            [^-\d:,] 除了(^) - 数字  : , \s
            \s 任意一个空白字符匹配,如空格,制表符\t,换行符\n
            \S 除了空白符外任意一个字符匹配
        */
        console.log(hd.match(/[^-\d:,\s]+/g));

image.png

/w /W

    /**
            \w 与任意一个英文字母、数字或下划线匹配
        */
        let str = 'houdunren2022-12_'
        console.log(str.match(/\w+/));
        console.log(str.match(/\w+/g));
        let email = "12345678@qq.com"
        let errEmail = "##@@@@12345678@qq.com"
        console.log(email.match(/\w@\w/));
        console.log(email.match(/\w@\w/g));
        console.log(email.match(/\w+@\w+\.\w+/g));
        console.log(email.match(/^\w+@\w+\.\w+$/g));
        console.log(errEmail.match(/\w+@\w+\.\w+/g));
        console.log(errEmail.match(/^\w+@\w+\.\w+$/g));
        console.log('----------------------------------');
        /**
            \W 除了字母、数字或下划线外的任何字符匹配
        */
        console.log('hfs_123@#$%^&'.match(/\W+/g));
        /**
            以字母开始,后跟字母数字下划线
            [a-z] a-z的任意
            ^....$ 限定起始和终止
        */
        let username = prompt("请输入用户名")
        console.log(/[a-z]\w{4,9}/.test(username));
        console.log(/^[a-z]\w{4,9}$/.test(username));

image.png

点-元字符的使用

        /*
            .(点):匹配除换行符外的任意字符
        */
        let str = `
            asdav!@#$%^&*_ /n {}><
            huanhangfu
        `
        console.log(str.match(/.+/g));
        console.log(str.match(/.+/sg)); // s为单行匹配
        console.log('-----------------');
        let url = "https://www.houdunren.com"
        console.log(url.match(/https:\/\/\w+\.\w+.\w+/))
        console.log('-----------------');
        /*
            空格是普通字符,匹配规则可以直接空格
            \s: 任意一个空白字符匹配,如空格,制表符\t,换行符\n
        */
        let tel = '010 - 99999999'
        console.log(tel.match(/\d+ - \d{8}/));
        console.log(tel.match(/\d+\s-\s\d{8}/));

image.png

匹配所有

可以使用 [\s\S] 或 [\d\D] 来匹配所有字符

        /**
            匹配所有字符
        */
        let str = 'ab'
        console.log(str.match(/[####b]/));
        let str1 = `
            <span>
                dsijfisdjf @$!#%!%#%
                _+  

            </span>
        `
        // [\s\S] [\d\D]
        console.log(str1.match(/<span>[\d\D]+<\/span>/g));
        console.log(str1.match(/<span>[\s\S]+<\/span>/g));

image.png

i与g模式修正符

模式修饰

把正则表达式的运行方式进行改变

正则表达式在执行时会按他们的默认执行方式进行,但有时候默认的处理方式总不能满足我们的需求,所以可以使用模式修正符更改默认方式。

修饰符说明
i不区分大小写字母的匹配
g全局搜索所有匹配内容
m视为多行
s视为单行忽略换行符,使用. 可以匹配所有字符
y从 regexp.lastIndex 开始匹配
u正确处理四个字符的 UTF-16 编码

i

将所有houdunren.com 统一为小写

g

使用 g 修饰符可以全局操作内容

        let str = 'hoUdunren'
        console.log(str.match(/u/));
        console.log(str.match(/u/i));
        console.log(str.match(/u/ig));
        console.log(str.replace(/u/gi, '$'));

image.png

m

用于将内容视为多行匹配,主要是对 ^和 $ 的修饰

    let str = `
            #1 js,200元 #
            #2 php,300元 #
            #3 mysql.com # 数据库
            #4 node.js,200元 #
        `
        // [{ name: 'js', price: '200元'}]
        /**
            * 0->

        */
        console.log(str.match(/\s*#\d+\s+.+\s+#\s+/g));
        /**
            m: 每一行单独对待
        */
        console.log(str.match(/^\s*#\d+\s+.+\s+#$/gm));
        let lessons = str.match(/^\s*#\d+\s+.+\s+#$/gm).map(v => {
            v = v.replace(/\s*#\d+\s*/, '').replace(/#/, '')
            // console.log(v.split(','))
            let [name, price] = v.split(',')
            return {name, price}
        })
        console.log(JSON.stringify(lessons, null, 2))

image.png

汉字与字符属性

u

  • 每个字符都有属性,如L属性表示是字母,P 表示标点符号,需要结合 u 模式才有效。其他属性简写可以访问 属性的别名网站查看。

  • 字符也有unicode文字系统属性 Script=文字系统,下面是使用 \p{sc=Han} 获取中文字符 han为中文系统,其他语言请查看 文字语言表

        let hd = 'houdunren2010.好好学习天天向上'
        // 使用\p{L}属性匹配字母
        console.log(hd.match(/\p{L}/gu));
        //使用\p{P}属性匹配标点
        console.log(hd.match(/\p{P}+/gu));
        // 匹配中文
        console.log(hd.match(/\p{sc=Han}+/gu));
        let str = "𝒳𝒴";
        console.log(str.match(/[𝒳𝒴]/gu));

image.png

lastIndex

RegExp对象lastIndex 属性可以返回或者设置正则表达式开始匹配的位置

  • 必须结合 g 修饰符使用
  • 对 exec 方法有效
  • 匹配完成时,lastIndex 会被重置为0
        let hd = 'houdunren.js'
        console.log(hd.match(/\w/));
        console.log(hd.match(/\w/g));
        let reg = /\w/g
        console.log(reg.lastIndex);
        console.log(reg.exec(hd));
        console.log(reg.lastIndex);
        console.log(reg.exec(hd));
        console.log(reg.exec(hd));
        console.log(reg.exec(hd));

image.png

        let hd = 'houdunren.js'
        console.log(hd.match(/\w/));
        console.log(hd.match(/\w/g));
        let reg = /\w/g; // 全局模式下会记录上一次搜索的位置
        while( res = reg.exec(hd)){
            console.log(res);
        }

image.png

y

        let hd = 'udunren'
        // g会忽略不符合的内容
        let reg = /u/g
        console.log(reg.exec(hd));
        console.log(reg.lastIndex);
        console.log(reg.exec(hd));
        console.log(reg.lastIndex);
        console.log(reg.exec(hd));
        console.log(reg.lastIndex);
        console.log('---------------------------------');
        // y不会忽略不符合的内容
        let reg1 = /u/y
        console.log(reg1.exec(hd));
        console.log(reg1.lastIndex);
        console.log(reg1.exec(hd));
        console.log(reg1.lastIndex);
        console.log(reg1.exec(hd));
        console.log(reg1.lastIndex);

image.png

    let hd = `后盾人QQ群:11111111,999999999,88888888
后盾人不断分享视频教程,后盾人网址是 houdunren.com`;
        let reg = /(\d+),?/y
        reg.lastIndex = 7
        console.log(reg.exec(hd));
        console.log(reg.exec(hd));
        console.log(reg.exec(hd));
        console.log(reg.exec(hd));

image.png

        let hd = `后盾人QQ群:11111111,999999999,88888888
后盾人不断分享视频教程,后盾人网址是 houdunren.com`;
        let reg = /(\d+),?/y
        reg.lastIndex = 7
        let qq = []
        while (res = reg.exec(hd)) qq.push(res[1])
        console.log(qq);  // ['11111111', '999999999', '88888888']

原子表

原子表 在一组字符中匹配某个元字符,在正则表达式中通过元字符表来完成,就是放到[] (方括号)中。

使用语法

原子表说明
[]只匹配其中的一个原子
[^]只匹配"除了"其中字符的任意一个原子
[0-9]匹配0-9任何一个数字
[a-z]匹配小写a-z任何一个字母
[A-Z]匹配大写A-Z任何一个字母
        let hd = 'houdunren'
        console.log(hd.match(/ue/))
        console.log(hd.match(/[ue]/g))
        let tel = '2022-02-23'
        let reg = /^\d{4}-\d{2}-\d{2}$/
        console.log(tel.match(reg));
        let tel1 = '2022/02/22'
        let tel2 = '2022/02-22'
        let reg1 = /^\d{4}[-\/]\d{2}[-\/]\d{2}$/
        console.log(tel1.match(reg1));
        console.log(tel2.match(reg1));
        let reg2 = /^\d{4}([-\/])一一对应\d{2}\1\d{2}$/ // \1与([-\/])一一对应
        console.log(tel2.match(reg2));
        console.log(tel1.match(reg2));

image.png

区间匹配、排除匹配

        let hd = 'houdunren345234'
        /**
            [] 原子表里只是代表一个字符
            原子表里面的内容只能是升序,不能是降序
        */
        console.log(hd.match(/[a-z]+/g));
        console.log(hd.match(/[0-9]+/g));
        console.log('----------------------');
        /**
            [^....] 原子表中的^表示除了原子表中的内容都要匹配
        */
        let str = 'houdunren.com'
        console.log(str.match(/[^ue]/gi));

        let hd1 = `
            张三: 010-99999999,李四: 020-88888888
        `
        console.log(hd1.match(/[^\d:\-,]+/g));

image.png

原子表字符不解析

        let hd = '(houdunren).+'
        console.log(hd.match(/[()]/gi));
        // console.log(hd.match(/()/gi));
        console.log(hd.match(/[.+]/gi)) // [] 内匹配 点 / 加号
        console.log(hd.match(/.+/gi)) // 原字符(点:匹配除换行符外的任意字符)

image.png

使用原子表匹配所有内容

        let hd = `
            houdunren
            hdcms
        `
        console.log(hd.match(/.+/gs));
        
        // [\s\S] \s 空白和 \S除了空白 == 所有 
        // [\d\D] 所有内容
        console.log(hd.match(/[\d\D]/g));

image.png

正则操作DOM元素

    <p>后盾人</p>
    <h1>houdunren.com 
        hhhhhhhhfffff
    </h1>
    <h3></h3>
    <h2>hdcmd.com</h2>
    <script>
        let body = document.body
        let reg = /<(h[1-6])>.+<\/\1>/gi; 
        // body.innerHTML = body.innerHTML.replace(reg, '')
        let reg1 = /<(h[1-6])>[\s\S]*<\/\1>/gi;
        body.innerHTML = body.innerHTML.replace(reg1, '')
    </script>

原子组

原子组

()括号包住的:原子组

        // ()括号包住的:原子组
        let hd = `
            <h1>feichichengzhang</h1>
            <h2>lishanglong</h2>
        `
        let reg = /<h[1-6]>[\s\S]*<\/h[1-6]>/ig // 前面的标签无法和后面的标签保持一致
        /**
            需要保持一致就要使用(),让其成组
            () 成组,获取就是 \1 \2...
        */
        let reg1 = /<(h[1-6])>[\s\S]*<\/\1>/ig // 标签的闭合标签有个/需要使用\转义
        console.dir(hd.match(reg1))
        let reg2 = /<(h[1-6])>([\s\S]*)<\/\1>/i // 标签的闭合标签有个/需要使用\转义
        console.dir(hd.match(reg2))

image.png

邮箱验证中原子组的使用

    <input type="text" name="mail" value="12345678@qq.com.cn">
    <script>
        let mail = document.querySelector(`[name="mail"]`).value
        let reg0 = /^[\w-]+@[\w-]+\.(com|org|cc|cn|net)$/i
        let reg = /^[\w-]+@([\w-]+\.)+(com|org|cc|cn|net)$/i
        console.log(mail.match(reg));
    </script>

原子组引用完成替换操作

    let hd = `
      <h1>houdunren</h1>
      <span>好好学习</span>
      <h2>study</h2>
    `
    /**
        1.标签的闭合标签有个/需要使用\转义
        2.需要保持一致就要使用(),让其成组
          () 成组,获取就是 \1 \2...
        3.replace,p0为所有字符,p1-pn为所有的原子组
    */
    let reg = /<(h[1-6])>(\w[\s\S]+)<\/\1>/gi;
    let res = hd.replace(reg, (p0, p1, p2, p3) => `<p>${p2}</p>`)
    console.log(res);

1.嵌套分组与不记录组

        let hd = `
            https://www.houdunren.com
            http://houdunwang.com
            https://baidu.com
        `
        // 正则匹配域名
        // 不记录分组
        // let reg = /https:\/\/(\w+\.\w+\.(com|org|cn))/i
        // let reg = /https:\/\/(\w+\.\w+\.(?:com|org|cn))/i
        /**
            
            原子组按从左到右的顺序
            第一个原子组 (\w+\.\w+\.(com|org|cn))
            第二个原子组 (com|org|cn)
            原子组前面加 ?: 忽略这个原子组
        */
        let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/ig
        /**
            ? 零次或一次
            原子组按从左到右的顺序
            第一个原子组 (?:\w+\.)?\w+\.(?:com|org|cn)
            第二个原子组 (?:\w+\.)
            第三个原子组 (?:com|org|cn)
            原子组前面加 ?: 忽略记录这个原子组
        */
        // console.dir(hd.match(reg));
        // console.dir(reg.exec(hd))
        // console.dir(reg.lastIndex)
        // console.dir(reg.exec(hd))
        // console.dir(reg.lastIndex)
        // console.dir(reg.exec(hd))
        // console.dir(reg.lastIndex)
        // console.dir(reg.exec(hd))
        // console.dir(reg.lastIndex)
        let urls = []
        while((res = reg.exec(hd))){
            // console.log(res[1]);
            urls.push(res[1])
        }
        console.log(urls) //  ['www.houdunren.com', 'houdunwang.com', 'baidu.com']

多种重复匹配基本使用

基本使用

如果要重复匹配一些内容时我们要使用重复匹配修饰符,包括以下几种。

符号说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

因为正则最小单位是元字符,而我们很少只匹配一个元字符如a、b所以基本上重复匹配在每条正则语句中都是必用到的内容。

        /**
            贪婪匹配
            +  一个或多个
            *  0个或多个
            {} 限定数量
            ? 0或1
        */
        let hd = 'hdddddddddddd'
        console.log(hd.match(/hd+/));
        console.log(hd.match(/hd*/));
        console.log(hd.match(/hd{1,3}/)); // 1-3
        console.log(hd.match(/hd{1,}/)); // 1->无限
        console.log(hd.match(/hd?/)); // 1->无限

image.png

重复匹配与原子组影响与电话号码正则

        let hd = 'hdddddddddddddddddddddhdh'
        console.log(hd.match(/hd+/));
        console.log(hd.match(/(hd)+/));
        let tel = '010-99999999'
        console.log(tel.match(/^0\d{2,3}-\d{7,8}$/));

image.png

网站用户名验证

    <input type="text" name="username">
    <script>
        document.querySelector(`[name='username']`).addEventListener('keyup', (e)=>{
            const value = e.target.value;
            let reg = /^[a-z][\w-]{2,7}$/i
            console.log(reg.test(value));
        })
    </script>

批量使用正则完成密码验证

    <input type="text" name="password">
    <script>
        let input = document.querySelector(`[name='password']`)
        input.addEventListener('keyup', (e) => {
            let value = e.target.value
            console.log(value)
            let regs = [/^[a-z0-9]{5,10}$/i, /[A-Z]/, /[0-9]/]
            let state = regs.every(e => e.test(value))
            console.log(state ? '正确' : '密码错误');
        })
    </script>

禁止贪婪

贪婪匹配+? 只获取最少的

        let hd = 'hdddd'
        console.log(hd.match(/hd+/));
        /**
            贪婪匹配+? 只获取最少的
        */
        console.log(hd.match(/hd+?/));
        console.log(hd.match(/hd*?/));
        console.log(hd.match(/hd{2,}?/));

image.png

标签替换的禁止贪恋使用

    <main>
        <span>houdunrenwang</span>
        <span>hdcms</span>
        <span>houdunren.com</span>
    </main>
    <script>
        /*span -> h4,描红 文字前加 后盾-*/
        const main = document.querySelector('main')
        // let reg = /<span>[\s\S]+<\/span>/ig // +:贪婪,会把所有匹配
        // let reg = /<span>[\s\S]+?<\/span>/ig
        let reg = /<span>([\s\S]+?)<\/span>/ig
        main.innerHTML = main.innerHTML.replace(reg, (v, p1) => {
            console.log(v);
            return `<h4 style="color:red;">后盾人-${p1}</h4>`
        })
    </script>

image.png

使用matchAll完成全局匹配

    <h1>houdunren.com</h1>
    <h2>hdcms.com</h2>
    <h1>后盾人</h1>
    <script>
        // 全局匹配标签内的内容
        // let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/i // 一个内容,非全局
        let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/ig
        
        const body = document.body;
        // console.dir(body.innerHTML.match(reg))
        /**
            matchAll
                得到的是一个迭代对象
                这个迭代对象可以遍历
        */
        // console.dir(body.innerHTML.matchAll(reg))
        const hd = body.innerHTML.matchAll(reg)
        const contents = []
        for(const iterator of hd) {
            // console.dir(iterator)
            contents.push(iterator[2])
        }
        console.log(contents); // ['houdunren.com', 'hdcms.com', '后盾人']

为低端浏览器定义原型方法matchAll

    <h1>houdunren.com</h1>
    <h2>hdcms.com</h2>
    <h1>后盾人</h1>
    <script>
        // matchAll
        /**
            matchAll
            低端浏览器中没有这个方法 
        */
        String.prototype.matchAll = function(reg) {
            let res = this.match(reg)
            if(res){
                let str = this.replace(res[0], '^'.repeat(res[0].length))
                let match = str.matchAll(reg) || []
                return [res, ...match]
            }
        }
        let hd = 'houdunren';
        // console.log(hd.matchAll(/u/i));
        // console.log(hd.matchAll(/(u)/i));
        let body = document.body;
        let search = body.innerHTML.matchAll(/<(h[1-6])>([\s\S]+?)<\/\1>/)
        console.log(search);

image.png

使用exec完成全局匹配

        let hd = 'houdunren'
        let reg = /u/gi
        console.log(reg.exec(hd));
        console.log(reg.lastIndex);
        console.log(reg.exec(hd)); // 会接着上一个的匹配往下,因为lastIndex,直到匹配不到为0
        console.log(reg.lastIndex);
    <h1>houdunren.com</h1>
    <h2>hdcms.com</h2>
    <h1>后盾人</h1>
    <script>
        // let hd = 'houdunren'
        // let reg = /u/gi
        // let result = []
        // while(res = reg.exec(hd)) {
        //     result.push(res)
        // }
        // console.log(result);
        function search(string, reg) {
            let result = []
            while (res = reg.exec(string)) {
                result.push(res)
            }
            return result
        }
        let matchs = search(document.body.innerHTML,/<(h[1-6])>([\s\S]+?)<\/\1>/gi)
        console.log(matchs);
    </script>

image.png

字符方法

下面介绍的方法是 String 提供的支持正则表达式的方法

  • search
  • match
  • matchAll
  • split
  • replace

search、match

search() 方法用于检索字符串中指定的子字符串,也可以使用正则表达式搜索,返回值为索引位置

        /**
            match 
            exec
            matchAll
            replace
        */
        // search 搜索
        let hd = "houdunren.com"
        console.log(hd.search('h'));
        console.log(hd.search(/u/));
        // match 匹配结果
        console.log(hd.match(/u/i));
        console.log(hd.match(/u/gi));
        let hd1 = `
            https://www.houdunren.com
            http://houdunwang.com
            https://www.sina.com.cn
        `
        // 网址匹配
        // let reg = /https?:\/\/(\w+\.)?\w+(\.(com|reg|org))+/gi
        let reg = /https?:\/\/(\w+\.)?(\w+\.)+(com|cn|org|cc)/gi
        console.log(hd1.match(reg));

image.png

matchAll

        let hd1 = `
            https://www.houdunren.com
            http://houdunwang.com
            https://www.sina.com.cn
        `
        // 网址匹配
        let reg = /https?:\/\/(?:\w+\.)?(\w+\.)+(?:com|cn|org|cc)/gi
        console.log(hd1.matchAll(reg));
        for (const iterator of hd1.matchAll(reg)) {
            console.log(iterator);
        }

image.png

split

        let hd = '2020-09-12'
        console.log(hd.split("-"));
        console.log(hd.split(/[-\/]/)); // ['2020', '09', '12']

replace

        let date = '2030/12/18'
        // 替换+正则
        date.replace(/\//g, '-') 
        let Tel = "(010)99999999 (020)88888888"
        // 010-999999999
        let reg = /\((\d{3,4})\)(\d{7,8})/g
        console.log(Tel.match(reg)); //  ['(010)99999999', '(020)88888888']
        /*
            \( 普通字符(
            $1 原子组一
            $2 原子组二
        */
        console.log(Tel.replace(reg, '$1-$2')); // 010-99999999 020-88888888

image.png

$& 符在正则替换中的使用

        /**
            $`(反引号)匹配内容前面的内容
            $'(引号) 匹配内容后面的内容
            $& 匹配到的内容
        */ 
        let hd = "=后盾人$"
        console.log(hd.replace(/后盾人/, "$&"));
        console.log(hd.replace(/后盾人/, "$`"));
        console.log(hd.replace(/后盾人/, "$'"));
        console.log(hd.replace(/后盾人/, "$`$`$&$'$'"));
    <main>在线教育是一种高效的学习方式,教育是一生的事业</main>
    <script>
        const main = document.querySelector('body main')
        main.innerHTML = main.innerHTML.replace(/教育/g, `<a href="https:www.baidu.com">$&</a>`)
    </script>

原子组

原子组在替换中的使用技巧

    <main>
        <a style="color: red;" href="http://www.baidu.com">百度</a>
        <a href="http://houdunren.com">后盾人</a>
        <a href="http://yahoo.com">雅虎</a>
        <h4>http://www/hdcms.com</h4>
    </main>
    <script>
        const main = document.querySelector('body main')
        const reg = /(<a.*href=['"])(http)(:\/\/)(www\.)?(hdcms|houdunren)/i
        main.innerHTML = main.innerHTML.replace(reg, (v, ...args) => {
            console.log('all', args);
            args[1] += 's'
            args[3] = args[3] || 'www.'
            // console.log(args.splice(0, 5).join);
            return args.splice(0, 5).join('')
        })
    </script>

原子组别名

原子组()的最前面使用?<别名>

    let hd = `
            <h1>houdunren.com</h1>
            <span>hdcms.com</span>
            <h1>后盾人</h1>
        `
        // const reg = /<(h[1-6])>(.*?)<\/\1>/gi
        const reg = /<(h[1-6])>(?<con>.*?)<\/\1>/gi
        // hd.replace(reg, '<h4>$2</h4>')
        hd.replace(reg, '<h4>$<con></h4>')

使用原子组别名优化正则

    <main>
        <a href="http://www.baidu.com">百度</a>
        <a href="http://houdunren.com">后盾人</a>
        <a href="http://yahoo.com">雅虎</a>
    </main>
    <script>
        // [{link:'',title:''}]
        const main = document.querySelector('body main')
        const reg = /<a.*?href=(['"])(?<link>.*)\1>(?<title>.*?)<\/a>/i
        // console.log(main.innerHTML.match(reg));
        const links = []
        for (const iterator of main.innerHTML.match(reg)) {
            console.log(iterator['groups']);
            links.push(iterator['groups'])
        }
        console.log(links);
    </script>

正则方法

正则方法test

  <input type="text" name="email">
  <script>
    const email = document.querySelector(`[name='email']`)
    email.addEventListener('keyup', (e) => {
      let value = e.target.value;
      let flag = /^[\w-]+@(\w+\.)+(com|org|cn)$/i.test(value)
      console.log(flag);
    })
  </script>

正则方法exec

不使用 g 修饰符时与 match 方法使用相似,使用 g 修饰符后可以循环调用直到全部匹配完。

  • 使用 g 修饰符多次操作时使用同一个正则,即把正则定义为变量使用
  • 使用 g 修饰符最后匹配不到时返回 null
    // 计算内容中后盾人出现的次数
    <main>后盾人不断分享视频教程,后盾人网址是 houdunren.com</main>
    <script>
        let reg = /后盾人/g
        const main = document.querySelector('body main')
        let count = 0;
        while(res = reg.exec(main.innerHTML)){
            count++
        }
        console.log(count);
    </script>

断言匹配

断言匹配

零宽先行断言

后面是什么

(?=exp)

零宽先行断言 ?=exp 匹配后面为 exp 的内容

    <main>后盾人不断分享视频教程,后盾人网址是 houdunren.com</main>
    <script>
        // 给后面接有网址的后盾人加上a标签
        let main = document.querySelector('body main')
        /**
            匹配内容(?=xxx) 匹配的内容后面是xxx的内容
        */
        let reg = /后盾人(?=网址)/g;
        /***
            $& 自身内容
        */
        main.innerHTML = main.innerHTML.replace(reg, `<a href="https://houdunren.com">$&</a>`)
    </script>
        // 使用断言规范价格
        let lessons = `
            js,200元,300次
            php,300.00元,100次
            node.js,180元,260次
        `
        let reg = /(\d+)(.00)?(?=元)/gi
        /**
            可先将所有的内容获取,去判断 .00原子组是否存在
            第一个原子组 (/d+)
            第二个原子组 (.00)
            (?=exp) 这个不是原子组
        */
        lessons = lessons.replace(reg, (v, ...args) => {
            // console.log(args);
            args[1] = args[1] || '.00'
            return args.splice(0, 2).join('')
        });
        console.log(lessons);

零宽后行断言

前面是什么

(?<=exp)

零宽后行断言 ?<=exp 匹配前面为 exp 的内容

    // 修改链接
    <a href="https://baidu.com">百度</a>
    <a href="https://yahoo.com">雅虎</a>
    <script>
        // let hd = 'houdunren789hdcms666'
        // const reg = /(?<=houdunren)\d+/gi
        // console.log(hd.match(reg));
        let reg = /(?<=href=(['"])).+(?=\1)/gi
        let body = document.body
        body.innerHTML = body.innerHTML.replace(reg, `htts://houdunren.com`)
    </script>

使用断言模糊电话号

        let users = `
            向军电话: 12345678901
            后盾人电话:98745675603
        `
        /*
            断言只是条件,不在匹配当中
        */
        let reg = /(?<=\d{7})\d{4}/gi;
        console.log(users.replace(reg, '****'));

image.png

零宽负向先行断言

后面不是什么

(?!exp)

零宽负向先行断言 后面不能出现 exp 指定的内容

        // ?= ?!
        let hd = "houdunren2010hscms"
        let reg0 = /[a-z]+(?!\d+)/gi;
        console.log(hd.match(reg0)); // ['houdunre', 'hscms']
        let reg = /[a-z]+(?!\d+)$/gi; // $限制[a-z] 表示以字母结尾
        console.log(hd.match(reg)); // ['hscms']

断言限制用户名关键词

        // 断言限制用户名关键词
        const input = document.querySelector(`[name='username']`)
        input.addEventListener('keyup', function(){
            // 不能包含向军
            const reg = /^(?!.*向军)[a-z]{5,6}*$/i
            console.log(this.value.match(reg));
        })

零宽负向后行断言

前面不是什么

(?<!exp)

零宽负向后行断言 前面不能出现exp指定的内容

        let hd = 'hdcms090houdunren'
        let reg = /(?<!\d+)[a-z]+/gi 
        console.log(hd.match(reg)); //  ['hdcms', 'oudunren']
        let reg1 = /^(?<!\d+)[a-z]+/gi // ^限定【a-z】
        console.log(hd.match(reg1)); // ['hdcms']
    <main>
        <a href="https://www.houdunren.com/1.jpg">1.jpg</a>
        <a href="https://oss.houdunren.com/2.jpg">2.jpg</a>
        <a href="https://cdn.houdunren.com/3.jpg">3.jpg</a>
        <a href="https://houdunren.com/2.jpg">后盾人</a>
    </main>
    <script>
        const main = document.querySelector('main')
        let reg = /https:\/\/([a-z]+)?(?<!oss)\..+?(?=\/)/gi
        main.innerHTML = main.innerHTML.replace(reg, v =>{
            console.log(v);
            return 'https://oss.houdunren.com'
        })
    </script>

学习笔记,来源后盾人

参考后盾人