js正则表达式

js正则表达式,js中的象形文字。正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式,可用于文本搜索和文本替换。

JS 正则表达式(RegExp对象)

  • 正则创建的两种方式 正则只是针对字符串 默认区分大小写
    1.patt=new Regexp('规则','g')或patt=new Regexp(/\d{6-10}/g) 动态创建规则必须是字符串 如有\或特殊字符需用\转义
    2.patt=/\d{6-10}/g 字面量方式 不要写引号 需要传参的时候必须用new Regexp
  • 正则的六个方法
    1./\d+/.test(字符串) 检索字符串中的指定值 返回truefalse
    2./\d+/.exec(字符串) 检索字符串中的指定值 返回值是被找到的值 没有返回null
    3.str.replace(/\d+/,"hello"或callback) 查找并替换 匹配成功返回替换后的字符串
    4.str.match(/\d+/) 正则去匹配字符串 匹配成功返回匹配成功的数组 不成功返回null
    5.str.search(/\d+/) 正则去匹配字符串 匹配成功返回位置,失败返回-1
    6.str.split(/-/) 用于使用字符串或正则表达式分隔字符串
    正则默认都是匹配成功就结束了,不会继续匹配,只匹配一次 要全部匹配则要加修饰符g(全局匹配)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    // new RegExp("e") 声明正则
    var str = "The best things is sleeping"
    var patt1 = new RegExp("e")
    console.log(patt1.test(str)) //true
    console.log(patt1.exec(str)) //["e", index: 2, input: "The best...", groups: undefined]
    var patt = /e/
    console.log(str.search(patt)) //2
    console.log(str.match(patt)) //["e", index: 2, input: "The best...", groups: undefined]
    console.log(str.replace(patt, 'E')) //ThE best things is sleeping
    // 使用 /\d{2}/ 声明正则
    var str = '我日西安水电费贱贵大傻逼阿达'
    var patt = /我日|贱|大傻逼/g
    var result = str.replace(patt,function(s){
    var res = ''
    for(var i=0;i<s.length;i++){
    res += '*'
    }
    return res
    })
    console.log(result) //**西安水电费*贵***阿达
    // 去掉前后空格
    var re1 = /^\s+|\s$/g
    console.log(' as da '.replace(re1, '')) //as da
    // 使用split分日期隔字符串
    let dateStr = '2020-09-08 16:18:22'
    dateStr.split(/-|:|\s/) // ['2020', '09', '08', '16', '18', '22']
  • 修饰符
    i 不区分大小写字母的匹配
    g 执行全局匹配
    m 执行多行匹配 放在/后面 /e/gi

  • 表达式
    [abc] 用于查找方括号之间的任意一个(字符类) /[abc]/
    [^abc] 用于查找任何不在方括号之间的字符 /[^abc]/
    | 或、左右两侧有一个匹配到就可以 a|b
    () 匹配子项或分组操作
    [a-z] 范围 [a-z]
    [\b] 退格直接量
    注: 匹配子项 把正则的整体叫做(母亲) 然后把左边第一个小括号里面的正则 叫做第一个子项(第一个孩子) 第二个小括号就是 第二个子项str.replace(patt,function(母亲,第一个子项,第二个子项){}

  • 元字符 转义字符
    . 查找除换行符之外任意字符
    \w 用于查找字符 字符包括[A-Za-z0-9_] \W 非字符 [^A-Za-z0-9_]
    \d 用于查找数字 0-9 \D 非数字
    \s 用于查找空白(空格 tab 回车 换行) \S 非空白
    \b 独立的部分(单词边界)(起始 结束 空格) \B 非独立的部分(非单词边界)
    \1或\2.. 重复的第一个子项,第二个子项

  • 量词(频率匹配) 匹配不确定的次数 大括号{} 量词
    + 一次或多次
    * 任意次
    ? 零次或一次
    {n} 必须是n次
    {n,} 至少n次
    {n,m} 最少n次,最多m次
    $ 匹配以某字符结尾
    ^ 匹配以某字符开始

  • 捕获分组和后向引用
    当一个模式的全部或者部分内容由一对括号分组时,它就对内容进行捕获并临时存储与内存中。可以通过后向引用重用捕获的内容。
    \1或者$1 这里\1或$1引用的是第一个捕获的分组,而\2或$2引用的是第二个捕获的分组,以此类推。

    1
    2
    3
    /(\w)\1+/g;    //(\w) 变成子项  \1和前面子项相同 +多个
    // \1 \2 \3……\9 \10 ---匹配模式中的后向引用
    // $1 $2 $3……$9 $10 ---替换模式中的组的引用
  • 捕获分组和非捕获分组
    () 表示捕获分组, ()会把每个分组里的匹配的值保存起来, 使用$n(n是一个数字, 表示第n个捕获组的内容)
    (?:) 表示非捕获分组, 和捕获分组唯一的区别在于, 非捕获分组匹配的值不会保存起来

    1
    2
    3
    4
    5
    6
    7
    8
    // 正则表达式中的每个`()`,都是一个子表达式,每个子表达式都会自动获得一个从`1`开始的编号替换时,可用`$n`,指代本次匹配中第`n`个子表达式的对应内容
    var reg = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(\d{2})(\d)(\d|X)$/
    var reg1 = /^(\d{2})(\d{4})(\d{4})(\d{2})(\d{2})(?:\d{2})(\d)(?:\d|X)$/
    var str = "14272619960919121X"
    console.log(reg.exec(str)) // 捕获分组
    // ['14272619960919121X', '14', '2726', '1996', '09', '19', '12', '1', 'X', ...]
    console.log(reg1.exec(str)) // (?:) 在分组中?:是只匹配不捕获
    // ['14272619960919121X', '14', '2726', '1996', '09', '19', '1', ...]
  • 前向声明(先行断言)或反前向声明(先行否定断言)

    1
    2
    3
    4
    5
    6
    7
    8
    // (?=字符) 或 (?!字符) 是不计入返回结果的
    //exp1(?=exp2) 前向声明 exp1只有在exp2前面才匹配
    //exp1(?!exp2) 反前向声明 exp1只有不在exp2前面才匹配
    var str = '90利率101%,总额100';
    var re = /\d+(?=%)/g; // 只匹配%前面紧跟的数字
    var re1 = /\d+(?!%)/g; // 只匹配不在%前面的数字
    console.log(str.match(re)) // ['101'] => 只匹配在%前面紧跟的数字
    console.log(str.match(re1)) // ['90', '10', '100'] => 只匹配不在%前面的数字
  • 后顾(后行断言)或负后顾(后行否定断言)

    1
    2
    3
    4
    5
    6
    7
    // (?<=exp2)exp1 只有exp1在exp2后面才匹配
    // (?<!exp2)exp1 只有exp1不在exp2后面才匹配
    var str = 'banana is 80, apple is $100, pear is 90元';
    var re = /(?<=\$)\d+/g; // 只匹配$后面紧跟的数字
    var re1 = /(?<!\$)\d+/g; // 只匹配不在$后面的数字
    console.log(str.match(re)) // ['100'] => 只匹配在$后紧跟的数字
    console.log(str.match(re1)) // ['80', '00', '90'] => 只匹配不在$后面的数字
  • 正则表达式 \1 \2 反向引用之类的问题

    1
    2
    3
    4
    5
    6
    7
    // \0 \1 \2 都要和正则表达式集合()一起使用
    // \1表示重复正则第一个圆括号内匹配到的内容
    // \2表示重复正则第二个圆括号内匹配到的内容
    var str = 'abdcbcdadcabce'
    console.log(str.split('').sort().join('').match(/([a-z])\1*/g)) // ["aaa", "bbb", "cccc", "ddd", "e"]
    var RegExp1 = /^(123)(456)\1$/ // 123456123
    var RegExp1 = /^(123)(456)\2$/ // 123456456

replace更多应用

  • 格式化字符串:正则表达式中的每个(),都是一个子表达式,每个子表达式都会自动获得一个从1开始的编号替换时,可用$n,指代本次匹配中第n个子表达式的对应内容

    1
    2
    3
    4
    5
    6
    var date = '20190108180155'
    var reg = /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/
    date.replace(reg, '$1年$2月$3日 $4:$5:$6') // "2019年01月08日 18:01:55"
    date.replace(reg, '$1-$2-$3 $4:$5:$6') // "2019-01-08 18:01:55"
    // 隐藏手机号中间4位
    '18855558888'.replace(/(\d{3})\d*(\d{4})/g, '$1****$2') // 188****8888
  • replace第二个参数为函数时,匹配几次执行几次

    1
    2
    3
    4
    5
    6
    let str = "19861289"
    const arr = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
    str = str.replace(/\d/g, function () {
    return arr[arguments[0]]
    })
    console.log(str) // 壹玖捌陆壹贰捌玖

其他

  • 使用正则test()第一次是true,第二次是false
    正则表达式 lastIndex 属性用于规定下次匹配的起始位置。RegExp.exec( ) 和 RegExp.test( ) 找到的,它们都以 lastIndex 属性所指的位置作为下次检索的起始点。lastIndex 属性是可读可写的, 需配合修饰符g使用
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var s1 = "1R1MRLPRL";
    var reg = /mrlp/ig;
    console.log(reg.test(s1)) // true
    console.log(reg.lastIndex) // 7
    console.log(reg.test(s1)) // false
    // 方法一 直接去掉 g
    var s1 = "1R1MRLPRL"
    var reg = /mrlp/i
    console.log(reg.test(s1)) // true
    console.log(reg.lastIndex) // 0
    console.log(reg.test(s1)) // true
    // 方法二 当必须使用g时 将lastIndex重置为0
    var s1 = "1R1MRLPRL"
    var reg = /mrlp/ig
    console.log(reg.test(s1)) // true
    console.log(reg.lastIndex) // 7
    reg.lastIndex = 0
    console.log(reg.test(s1)) // true

贪婪匹配与惰性匹配

  • 默认贪婪匹配
    贪婪匹配是先看整个字符串是否匹配,如果不匹配,它会去掉字符串的最后一个字符,并再次尝试。如果还不匹配,那么再去掉当前最后一个,直到发现匹配或不剩任何字符

    1
    2
    3
    4
    var str = 'aaa<div style="font-color:red;">123456</div>bbb'
    str.match(/<.+>/); // <div style="font-color:red;">123456</div>
    var str2 = 'abcdabceba'
    str.match(/.+b/) // abcdabceb
  • ?惰性匹配 尽可能少的匹配
    惰性匹配是从左侧第一个字符开始向右匹配, 先看第一个字符是不是一个匹配, 如果不匹配就加入下一个字符再尝式匹配, 直到发现匹配

    1
    2
    3
    4
    var str = 'aaa<div style="font-color:red;">123456</div>bbb'
    str.match(/<.+?>/) // <div style="font-color:red;">
    var str2 = 'abcdabceba'
    str.match(/.+?b/) // ab
-------------本文结束感谢您的阅读-------------
0%