正则表达式

1,476 阅读5分钟

1.正则表达式创建方式
//字面量形式
console.log(/a/.test(str))

//对象的形式
let reg = new RegExp('h','g')
console.log(reg.test(str))
2.使用对象的方式创建正则表达式
let con = prompt("请输入需要搜索的内容")
let reg = new RegExp(con,'g')
let div = document.querySelector("div")
div.innerHTML = div.innerHTML.replace(reg,search =>{
    return `<span style="color:red">${search}</span>`
})
//获取用户想要搜索的内容  , 创建正则表达式 , 全局替换,将正则匹配到的数据添加样式
3.选择符的使用 |
//   | 或者符号
let str = 'hello world'
//只要 str 中包含 a 或者 u 就会返回 true
console.log(/a|u/.test(str))

let tel = '010-99999999'
//以 010 或者 020 开头  加上 - 符号, 后面是7-8位数字
console.log(/^(010|020)\-\d{7,8}$/.test(tel))
4.原子表与原子组的选择符 [] ()
//原子表 [] 匹配其中的一个 比如 [123] 可以匹配 1 或者 2 或者 3
//原子组() 匹配的是一组  比如 (123) 表示只能匹配 123 匹配 1 或者 2之类的就会出错
5.转义 \
// 在字面量正则和对象创建正则里面 转义是不同的 
let  price = 23.45
//匹配 数字一个或多个  .号符  后面再是一个或多个数字
// .号符如果不转义   就表示除了换行符之外的一切
console.log(/\d+\.\d+/.test(price))

//在对象创建正则里面,需要给 \d 加上一个转义符,不然 \d 会被解析成一个 d 字母
let reg = new RegExp('\\d+\\.\\d+')
console.log(reg.test(price))
6.字符边界约束 ^ $
let n = 'baidu2222222baidu'
// 不加字符边界的结果
console.log(/\d/.test(n))  //true  表示字符串中只要有数字即可

//加字符边界  ^ 表示开头  $ 表示结尾
console.log(/^\d$/.test(n))  //false  只匹配一个数字

//以开头是数字
console.log(/^\d/.test(n))

//以数字结尾
console.log(/\d$/.test(n))

document.querySelector("[name='user']").addEventListener("keyup",function(){
    //要使用 this 所以使用的函数表达式,而不是箭头函数
    //以字母开头,字母的数量在 3-6 之间
    let flag = this.value.match(/^[a-z]{3,6}/)
    //成功的时候返回成功数组,失败的时候返回 null
    document.querySelector("span").innerHTML = flag?"正确":"失败";
})
7.数值与空白元字符 \d \s
let str = 'hello world 2021'
console.log(str.match(/\d+/g))    //[2021]

let str2 = `
   张三:010-11111111,
   李四:020-22222222
`
//获取电话号码
console.log(str2.match(/\d{3}-\d{7,8}/g))
//[010-11111111,020-22222222]

// [] 里面的 ^ 表示取反
//除了 : - 数字 , 这些符号之外 , 就只有空格和中文了
console.log(str2.match(/[^:-\d,]/g))

// \s 解决空格
console.log(str2.match(/[^:-\d,\s]/g))
//['张','三','李','四']

//使原本就在一起中文拼接在一起 +
console.log(str2.match(/[^:-\d\s,]+/g))
//["张三","李四"]
8.w 字符和 \w 元字符
// \w  和  \W
//   \w 表示数字字母下划线  \W 除了数字字母下划线之外的一切
let str = 'helloworld2021'
console.log(str.match(/\w+/))  //helloworld2021

let email = '123@123.com'
console.log(email.match(/^\w+@\w+\.\w+$/))
// '123@123.com'

//字母开头 后面是数字字母下划线都行  5-10位
let username = prompt("请输入用户名")
console.log(/^[a-zA-Z]\w{4,9}$/.test(username))
  1. . 元字符
    //  .  除了换行符之外的一切    空格和换行符是两个东西
    let str = 'hello world'
    //匹配除了换行符之外的一切
    console.log(str.match(/.+/))
    
    //https://  可有可无
    let url = 'https://www.baidu.com'
    console.log(url.match(/(https:\/\/)?\w+\.\w+.\w+/))
    
    //s 可以忽视空格
    let str2 =`
       baidu.com
       jd.com
    ` 
    console.log(str2.match(/.+/s)[0])
    
    // \s 
    let tel = '010 - 99999999'
    console.log(tel.match(/\d{3} - \d{7,8}/))
    console.log(tel.match(/\d{3}\s-\s\d{7,8}/))
    
  2. 匹配所有字符 \s\S \d\D
let str = `
       <span>
             1231
             avasdas
             3##!%^&*
             SAGYSUID
             DSFHAUISDAsdhafuisp
             上帝就发iOS的哈
       </span>
`
// . 除了换行符之外的一切  \d 数字  \w 数字字母下划线
let str2 = 'ab33333333^^'
//只要是 [] 里面的都可以匹配
console.log(str2.match(/[ab1234567890^@#$%&*]+/))

//匹配所有 
// [\s\S]   [\d\D]
//所有的都能匹配
console.log(str.match(/<span>[\s\S]+<\/span>/))
11.模式修正符
//i   不区分大小写
//g   全局匹配
//gi  可以混合 全局匹配且不区分大小写
let hd = "houdunren"
console.log(hd.match(/u/gi))   //['u','u']

//全局替换 u 为 @ 且不区分大小写
console.log(hd.replace(/u/gi,'@'))   //ho@d@nren
12.多行匹配修正符
let str = `
  #1 js,200元 #
  #2 php,300元 #
  #3 java,400元 #
  #4 node.js,200元 #
`

//需要把格式整理为 [{name:'js',price:'200元'}]
let lessons = str.match(/^\s*#\d+\s*.+\s*#$/gm).map(v =>{
    v = v.replace(/\s*#\d+\s*/,'').replace(/\s*#/,'')
    let arr = v.split(',')
    return {name:arr[0],price:arr[1]}
})
console.log(lessons)
console.log(JSON.stringify(lessons))
13.汉字与字符属性
//中文 
let hd = 'houdunren.不断发布教程'
// 获取所有的字 不包括符号
console.log(hd.match(/\p{L}/gu))
//获取所有的符号
console.log(hd.match(/\p{P}/gu))
//获取所有的汉字
console.log(hd.match(/\p{sc=Han}/gu))

//宽体字 需要用 u
let str = '中文就是宽体字'
//如果想要匹配到宽体字就必须使用 u
console.log(str.match(/\p{sc=Han}/u))
  1. lastIndex 属性
//lastIndex的使用 
//用于规定下次匹配的起始位置  该属性只有配置标志  g  才能使用
//上次匹配的结果是由方法 RegExp.exec() 和 RegExp.test()  找到的
let hd = "houdunren"
let reg = /\w/g
console.log(reg.lastIndex)   //0
console.log(reg.exec(hd))  //h 
console.log(reg.lastIndex)  //1
console.log(reg.exec(hd))   //o

while((res = reg.exec(hd))){
    console.log(reg.lastIndex) //0-9  九次弹出
    console.log(res)  // 'h'  , 'o' ,'u'.......'n'   九次分别弹出
}
15.有效的 y 模式
let hd = "说的话四大行撒大苏打:11111111,22222222,33333333谁都不爱手段是丢啊是大束带苏丹哈桑www.baidu.com"
let arr = []
//g  适合全局  要获取的数据不连贯的时候
console.log(hd.match(/\d+,?/g))
//[ '11111111,' , '22222222,' , '33333333' ]
//y适合局部  要获取的数据连贯的时候   不连贯获取不到
let reg = /\d+,?/y
reg.lastIndex = 11   //要设置开始的位置
while((res = reg.exec(hd))){
    arr.push(res[0])
}
console.log(arr)
//[ '11111111,' , '22222222,' , '33333333' ]
16.原子表的使用
let hd = "houdunren"
console.log(hd.match(/[ue]/g))
// ['u','u','e']

//年月日  / - 符号分割
let date = "2020-02-11"
//下面两个正则其实是一样的
let reg = /^\d{4}[-/]\d{2}[-/]\d{2}/
let reg = /^\d{4}([-/])\d{2}\1\d{2}/
console.log(date.match(reg))
17.原子表区间匹配
<input type="text" name="username">
<script>
    let num = '2010'
    console.log(num.match(/[0-9]+/g))
    
    let hd = "houdunren"
    console.log(hd.match(/[a-z]+/g))
    
    let input = document.querySelector('[name="username"]')
    input.addEventListener("keyup",function(){
        console.log(this.value.match(/^[a-z]\w{3,6}$/i))
        //console.log(/^[a-z]\w+$/i.test(this.valaue))
    })
</script>
18.排除匹配
// ^ 排除
let hd = 'houdunren.com'
console.log(hd.match(/[^ue]/gi))
//['h', 'o', 'd', 'n', 'r', 'n', '.', 'c', 'o', 'm']     除了ue之外的一切

let str = '张三:010-11111111,李四:020-22222222'
//获取字符串中的中文
//1. 排除法
console.log(str.match(/[^:-\d,]+/g))

//2. 匹配
console.log(str.match(/\p{sc=Han}+/gu))
19.原子表字符不解析
//原子表字符不解析
let hd = '(houdunren).+'
console.log(hd.match(/[.+]/gi))
//['.' , '+']
console.log(hd.match(/[()]/g))
// ['(' , ')']

//在原子表中的字符不会解析,就是代表字符本身 
20.原子表匹配所有内容
let hd = `
    houdunren
    hdcms
`
//s  使用 s 之后特殊字符圆点中包含换行符  \n
consol.log(hd.match(/.+/gs))
//['\n          houdunren\n          hdcms\n        ']

//[\s\S]    [\d\D]   表示所有内容
console.log(hd.amtch(/[\s\S]+/)[0])
//  houduanren
//  hdcms      两个数据是一起弹出的 包含空格和换行
21.正则表达式操作DOM 元素
<body>
    <h1>后盾人教育</h1>
    <div> this is houdunren.com</div>
</body>
<script>
    let body = document.body
    let reg = /<(h[1-6])>[\s\S]*<\/\1>/gi
    //全局匹配 h1-h6标签 中间可以是任何数据
    
    //把 上面的 h1 标签 替换成了空字符  等于是删除了 h1 标签
    body.innerHTML = body.innerHTML.replace(reg,'')
</script>
22.认识原子组
let str = `
   <h1>string1</h1>
   <h1>string2</h1>
`
let reg = /<(h[1-6])>[\s\S]*<\/\1>/i
console.log(str.match(reg))
  // [    0: "<h1>string</h1>"
        //      1: "h1"            //  1代表的什么
        //      groups: undefined  //  组名
        //      index: 13          // 起始位置
        //      input: "\n     <h1>string</h1>\n   <h2>string2</h2>\n        " //原始数据
        //      length: 2]   
23.邮箱认证原子组的使用
<body>
    <input type="email" name="userEmail">
    <span></spanspan>
</body>
<script>
    let email = document.querySelector(`[name="userEmail"]`)
    emial.addEventListener("keyup",function(){
       let reg = /^[\w-]+@([\w-]+\.){1,2}(com|cn|org|cc|net)$/i
        document.querySelector("span").innerText = reg.test(this.value)?'正确':'失败'
    })
</script>
24.原子组引用完成替换操作
let hd = `
   <h1>houdunren</h1>
   <span>后盾人</span>
   <h2>hdcms</h2>
`
let reg = /<(h[1-6])>([\s\S]+)<\/\1>/gi
//完成了替换  先匹配到符合正则的数据 然后进行替换
// $2 表示 第二个 () 里面的数据  这里是 [\s\S]+   即标签中的所有内容
console.log(hd.replace(reg,`<p>$2</p>`))
//此时等同于把所有的 h1 标签 替换成 标签 , 标签中的文本不变
        //  <p>houdunren</p>
        //  <span>后盾人</span>
        //  <p>hdcms</p>

let res = hd.replace(reg,(p0,p1,p2)=>{
    console.log(p0)   // 匹配到的元素   两个 h1/h2 标签的内容
    console.log(p1)   // 第一个()里面的内容   h1  h2
    console.log(p2)   //第二个 () 里面的内容  houdunren       hdcms
})
25.嵌套分组与不记录分组
let hd = `
     https://www.houdunren.com
     http://www.baidu.com
     https://hdcms.com
`
let reg = /^https?:\/\/(\w+\.)?\w+\.(com|cn|org)$/gi
console.dir(hd.match(reg))
        // [
        //   0: "https://www.houdunren.com"
        //   1: "http://www.baidu.com"
        //   2: "https://hdcms.com"
        //   length: 3
        //]
//?:   不会记录当前组
let reg2 = /^https?:\/\/((?:\w+\.)?\w+\.(?:com|cn|org))$/gi
console.dir(hd.match(reg2))

let urls = []
while((res = reg2.exec(hd))){
    urls.push(res[1])
}
console.log(urls)
26.多种重复匹配的基本使用
let hd = "hdddddd"
//*   ?  +  {}   贪婪的匹配模式
//+  一个或多个
console.log(hd.match(/hd+/))   // "hdddddd"
//?  零个或一个
console.log(hd.match(/hd?/))    //"hd"
//*  零个一个或多个
console.log(hd.match(/hd*/))     //"hdddddd"
//{}  区间匹配  会往多的匹配 如果 (1,)就会有多少个匹配多少个
console.log(hd.match(/hd{1,4}/))  //"hdddd"
27.重复匹配对原子组的影响与电话号正则
let hd = "hdhdhdhddddddddddddddddddddddddhd"
console.log(hd.match(/hd+/g))
// ['hd', 'hd', 'hd', 'hddddddddd', 'hd']

console.log(hd.match(/(hd)+/g))
// ['hdhdhdhd', 'hd']

//电话号正则
let tel = `010-99999999`
console.log(tel.match(/^o\d{2,3}-\d{8,9}$/))
28.网站用户名验证
<body>
    <input type="text" name="username">
</body>
<script>
    document.querySelector(`[name="username"]`).addEventListener("keyup",function(e){
        let res = e.target.value
        let reg = /^[a-zA-Z][\w-]{2,7}$/
        console.log(reg.test(res))
    })
</script>
29.批量使用正则完成密码验证
<body>
    <input type="text" name="password">
</body>
<script>
    document.querySelector(`[name="password"]`)
        .addEventListener("keyup", e=>{
        let value = e.target.value
        //密码5-10位 必须包含大写字母和数字
        const reg = [
            /^[a-z0-9]{5,10}$/i,
            /[A-Z]/,
            /[0-9]/
        ]
        let state = reg.every(e =>{
            return e.test(value)
        })
        console.log(state)
    })
</script>
30.禁止贪婪
//? 禁止贪婪
let hd = `hddddd`
console.log(hd.match(/hd+?/))    //hd
console.log(hd.match(/hd{2,}?/))   //hdd
31.标签替换的禁止贪婪使用
<main>
    <!-- 替换 span 为 h4   标红    加  后盾人-->
     <span>123123123</span>
     <span>123123123</span>
     <span>123123123</span>
</main>
<script>
    const main = document.querySelector('main')
    const reg = /<span>([\s\S]+?)<\/span>/gi
    main.innerHTML = main.innerHTML.replace(reg,(v,p1)=>{
        return `<h4 style="color:red;">后盾人-${p1}</h4>`
    })
</script>
32.使用matchAll完成全局匹配
<body>
    <h1>12312312A</h1>
    <h1>12312312B</h1>
    <h1>12312312C</h1>
</body>
<script>
    let reg = /<(h[1-6])>([\s\S]+?)<\/\1>/gi
    const body = document.body
    const hd = body.innerHTML.matchAll(reg)
    let arr = []
    for(const iterator of hd){
        console.log(iterator)
        arr.push(iterator[2])
    }
    console.log(arr)
    //   ['12312312A', '12312312B', '12312312C'] 
</script>
33.使用exec完成全局匹配
<body>
    <h1>123123</h1>
    <h1>123123</h1>
    <h1>123123</h1>
</body>
<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>
34.字符串正则方法search与match
let hd = "houdunren.com"
//search  返回要匹配的字符串在字符串中首次出现的位置
//没有返回 -1
console.log(hd.search(/u/g))
let str = `
    https://www.baidu.com
    http://www.jd.com
    https://www.sinna.com.cn
`
let reg = /^https?:\/\/(www\.)?(\w+\.){1,2}(com|cn)$/gi
console.log(str.match(reg))
35.字符串正则方法 matchAll 和 split
let hd = `
    https://www.baidu.com
    http://www.jd.com
    https://www.sinna.com.cn
`
let reg = /^https?"\/\/(www\.)?(\w+\.)+(com|cn)$/gi
for(const iterator of hd.matchAll(reg)){
    console.log(iterator)
}

let time1 = '2020/09/01'
let time2 = '2020-09-12'
console.log(time1.split(/[-\/]/))
console.log(time2.split(/[-\/]/))
36.$符号在正则替换中的使用
let tel = '2020/1/11'
console.log(tel.replace(/\//g,'-'))

let hd = `
   (010) 99999999
   (0201) 88888888
`
let reg = /\((\d{3,4})\)\s(\d{8,9})/g
console.log(hd.match(reg))
console.log(hd.replace(reg),"$1-$2")
//  010-99999999      0201-88888888
37.$& 的使用
<main>
    在线教育是一种高效的学习方式,教育是一生的事业
</main>
<script>
    const main = document.querySelector("body main")
    main.innerHTML = main.innerHTML.replace(/教育/g,
         `<a href="https://www.baidu.com">$&</a>`                          
     )
    // $&     教育   
</script>
38。原子组在替换中的使用技巧
<main>
        <a style="color:red" href="http://www.hdcms.com">开源系统</a>
        <a href="http://houdunren.com">后盾人</a>
        <a href="http://yahoo.com">雅虎</a>
        <h4>http://www.hdcms.com</h4>
</main>
<script>
    //需要改造成 https://www.xxx.com
    const main = document.querySelector("body main")
    let reg = /(<a>.*href=['"])(http)(:\/\/)(www\.)?(hdcms|houdunre)(\.)(com|cn)/gi
    main.innerHTML = main.innerHTML.replace(reg,(v,...args)=>{
        console.log(v)
        console.log(..args)
        args[1] += 's'   //http  += 's'
        args[3] = args[3]  || 'www.'    //www.是否存在,存在不加,不存在加
        return args.splice(0,5).join("")
    })
</script>
39.原子组别名
let hd = `
   <h1>houdunren</h1>
   <span>后盾人</span>
   <h2>hdcms</h2>
`
const reg = /<(h[1-6])>(.*?)<\/\1>/gi
console.log(hd.replace(reg,`<h4>$2</h4>`))
//   ?<con>   这里是起别名
const reg2 = /<(h[1-6])>(?<con>.*?)<\/\1>/gi
console.log(hd.replace(reg2,`<h4>$<con></h4>`))
40.使用原子组别名优化正则
<main>
    <a id="a" href="https://www.baidu1.com">后盾人</a>
    <a id="a" href="https://www.baidu2.com">后盾人</a>
    <a id="a" href="https://www.baidu3.com">后盾人</a>
</main>
<script>
    const main = document.querySelector("main")
    const reg = /<a.*?href=(['"])(?<link>.*?)\1>(?<title>.*?)<\/a>/gi
    const links=[]
    for(const iterator of main.innerHTML.matchAll(reg)){
        link.push(iterator['groups'])
    }
    console.log(links)
</script>
41.正则方法test
const emial = document.querySelector(`[name="email"]`)
email.addEventListener("keyup",function(e){
    let value = e.target.value
    let reg = /^[\w-]+@([\w]+\.)+(com|cn|cc)$/i
    let flag = reg.test(value)
    console.log(flag)
})
42.正则方法 exec
<main>
    构造函数  原型离不开构造函数
    构造函数  原型离不开构造函数
</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>
43.断言匹配
<main>
    后盾人不断分享视频教程,学习后盾人教程提升编程能力
</main>
<script>
    //?=  断言匹配
    let main = document.querySelector("body main")
    let regOld = /后盾人/g
    let reg = /后盾人(?=教程)/g
    main.innerHTML = main.innerHTML.replace(reg,`
         <a href="https://houdunren.com">$&</a>
    `)
</script>
44.使用断言匹配规范价格
let lessons = `
         js,200元,300次
         php,300.00元,100次
         node.js,180元,260次
`
let reg = /(\d+)(.00)?(?=元)/gi
lessons = lessons.replace(reg,(v,...args)=>{
    args[1] = args[1] || '.00'
    return args.slice(0,2).join("")
})
console.log(lessons)
45.断言匹配2
<body>
    <main>
        <a href="https://baidu.com">百度</a>
        <a href="https://yahoo.com">雅虎</a>
    </main>
    <script>
        const main = document.querySelector("main")
        const reg = /(?<=href=["']).+(?=["'])/gi
        main.innerHTML = main.innerHTML.replace(reg,'https://www.houdunren.com')
        
        let hd = "houdunren789hdcms666"
        const reg2 = /(?<=houdunren)\d+/i
        console.log(reg2.test(hd))    //数字前面必须是字符串 houdunren
    </script>
</body>
46.使用断言匹配模糊电话号码
let users = `
   亚索:  18117098030
   后盾人: 18717191629
`
let reg = /(?<=\d{7})\d{4}/gi
users = users.replace(reg,v=>{
    return "*".replace(4)
})
console.log(users)
47.断言匹配
let hd = "houdunren2010hdcms"
let reg = /[a-z]+(?!\d+)$/i
console.log(hd.match(reg))    //hdcms   取得字符串后面不是数字的字符串段
48.断言匹配限制用户名关键词
<main>
    <input type="text" name="username">
</main>
<script>
    const input = document.querySelector(`[name="username"]`)
    input.addEventListener("keyup",function(){
        //?! 不允许出现
        //用户名中不允许出现 .- ? 三个字符
        const reg = /^(?!.*[\.\-?].*)[\s\S]{5,10}$/
        console.log(this.value.match(reg))
        //当输入框中包含 . - ? 三个符号的时候得到的是 null
    })
</script>
49.断言匹配
let hd = 'hdcms123123houdunren'
//字母前面不是数字的
let reg = /(?<!\d+)[a-z]+/i
console.log(hd.match(reg))
50.使用断言排除法统一数据
<main>
        <a href="https://www.houdunren.com/1.jpg">1.jpg</a>
        <a href="https://oss.houdunren.com/1.jpg">2.jpg</a>
        <a href="https://cdn.houdunren.com/1.jpg">3.jpg</a>
        <a href="https://houdunren.com/1.jpg">4.jpg</a>
</main>
<script>
    const main = document.querySelector("main")
    const reg = /https:\/\/([a-z]+)?(?<!oss)\..+?(?=\/)/gi
    main.innerHTML = main.innerHTML.replace(reg,v=>{
        return "https://oss.houdunren.com"
    })
</script>