• JS 正则 长篇


    正则

    正则:
    一个规则, 用来处理字符串的一个规则

    处理:

    处理

    reg.test(str)

    判断一个字符串是否复合我们的制定的规则

    var reg = /d/;
    console.log(reg.test("lemon22")); // true
    console.log(reg.test("lemon"));   // false
    

    捕获

    reg.excec(str)

    把字符串中符合正则规则的内容捕获到

    var reg = /d/;
    console.log(reg.exec("lemon")); // null
    console.log(reg.exec("1")); // ["1", index: 0, input: "1"];
    

    如何创建一个正则

    字面量方式:

    var reg = /d/;
    

    实例创建方式

    var reg = new RegExp("");
    

    两种方式创建区别

    需要动态创建正则表达式:

    • 在字面量方式中, 我们//之间包起来的所有的内容都是元字符, 有的具有特殊的意义, 大部分代表本身含义的普通的元字符
    var name = "lemon"
    var reg = /^d+"+name+"d+$/g
    console.log(reg.test('22"""lemon""22')) // true
    
    • 对于这样的需求, 我们只能使用实例创建的方式了
    var name = "lemon"
    var reg = new RegExp("^\d+" + name +"\d+%", "g")
    console.log(reg.text("22lemon""")) // true
    

    字面量和实例创建的方式在正则中的区别?

    • 字面量方式中出现的一切都是元字符, 所以不能进行变量值的拼接, 而实例创建的方式是可以的
    • 字面量方式中直接写d就行了, 在实例创建方式中需要把它转移 d

    元字符

    每一个正则表达式都是由元字符和修饰符组成的,

    元字符:
    在//之间具有意义的一些字符

    1.常用特殊意义的字符

    • : 转移字符, 转移后面字符所代表的含义
    • : 匹配一个换行符
    • . : 除了 以外的任意字符
    • ( ): 分组, 把一个大正则本身划分为几个小的正则
    • x | y: x或者y中的一个字符
    • [xyz ]: x或者y或者z中的一个字符
    • [^xyz]: 除了三个以外的任何一个字符
    • [a-z]: a-z之间的任何一个字符
    • [^a-z]: 除了a-z之间的任何一个字符
    • d: 一个0-9之间的数字
    • D: 除了0-9之间的数字以外的任何字符
    • : 一个边界符 "a b" -> "ab"
    • w: 数字, 字母, 下划线中的任意字符 等价于 [0-9a-zA-z_]
    • s: 匹配一个空白字符 空格, 一个制表符, 换页符....

    2.代表出现次数的量词元字符

    • *: 出现0到多次
    • +: 出现一次到多次
    • ?: 出现零或一次
    • {n} : 出现n次
    • {n, }: 出现n到多次
    • {n, m}: 出现n到m次

    3. 定位符,

    • ^: 以某一个元字符开始
    • $: 以某一个元字符结束
    • : 匹配位于每个单词的开始或结束的位置
    • B: 匹配每个每个单词的不是开始或结束的位置,即单词中间的位置
    • A: 匹配字符串的开始位置
    • : 匹配字符串的结束位置

    注意:

    [ ]: 中出现的所有的字符都代表本身意思的字符(没有特殊的含义)

    分组

    改变优先级

    var reg = /^18|19$/
    

    18, 19, 181, 189, 119, 819, 1819...

    var reg = /^(18|19)$/
    

    18, 19

    中括号不识别两位数

    var reg = /^[12-68]$/
    

    1, 2-6中的一个, 8

    示例

    匹配有效数字
    var reg = /^[+-]?(d|([1-9]d+))(.d+)?$/
    

    [+-]?
    可以有+或-, 或者都没有

    (d|([1-9]d+))
    单个数字(包括0), 或者以1到9开头的多位数字

    (.d+)?
    以.开头的多位数字, 或者都没有

    年龄介于18-65之间
    var reg = /^(1[8-9]|[2-5]d|6[0-5])$/
    
    邮箱(简版)

    1144411@qq.com
    123456@163.com.cn
    lemon@lemon.cn
    lemon_xu_22@163.com

    左边: 数字, 字母, 下划线, ., -
    @
    右边:

    var reg = /^[w.-]+@[0-9a-zA-z]+(.[a-zA-Z]{2,4}){1,2}$/
    

    标准真实姓名 2-4位汉字

    var reg = /^[u4e00-u9fa5]{2, 4}$/
    

    身份证号码(简版)

    var reg = /^d{17}(d|X)$/
    

    捕获

    捕获的内容格式:
    每一次捕获的时候都是先进行默认的匹配, 如果没有匹配成功的, 捕获的结果是null; 只有有匹配的内容才能捕获到:

    • 捕获到的内容是一个数组
      • 数组中的第一项是当前大正则捕获到的内容
      • index: 捕获内容在字符串中开始的索引位置
      • input: 捕获的原始字符串

    懒惰性, 贪婪性

    正则捕获的特点

    • 懒惰性: 每一次执行exec只捕获第一个匹配的内容, 在不进行处理的情况下, 在执行多次捕获, 捕获的还是第一个匹配的内容
      • lastIndex: 是正则每一次捕获在字符串中开始查找的位置
    • 贪婪性: 正则的每一次捕获都是按照匹配最长的结果捕获的, 例如: 2符合正则, 2020页符合正则, 我们默认捕获的是2020
    var reg = /d+/;
    var str = "lemon2020age22";
    var res = reg.exec(str);
    console.log(res);
    

    解决懒惰性

    在正则的末尾加一个修饰符"g"

    修饰符:g, i, m

    • global(g): 全局匹配
    • ignoreCase(i): 忽略大小写匹配
    • multiline(m): 多行匹配

    加了全局修饰符g, 正则每一次捕获结束后, 我们的lastIndex的值都变为了最新的值, 下一次捕获从最新的位置开始查找, 这样就可以把所有需要捕获的内容都捕获到了

    var reg = /d+/g;
    var str = "lemon2020age22";
    console.log(reg.lastIndex);
    console.log(reg.exec(str));
    console.log(reg.lastIndex);
    console.log(reg.exec(str));
    

    0
    Array["2020", ...]
    9
    Array["22", ....]

    编写程序获取正则捕获的所有内容(正则一定不要忘记加g)
    var reg = /d+/g;
    var str = "lemon2020age22";
    var ary = [ ];
    var res = reg.exec(str);
    while(res) {
        ary.push(res[0]);
        res = reg.exec(str);
    }
    console.log(ary)
    

    ["2020" , "22"]

    解决正则贪婪性

    只需要在量词元字符后面添加一个?即可

    var reg = /d+?/g;
    var str = "lemon2020age22";
    console.log(reg.exec(str));
    

    ["2", ....]

    ?在正则中有很多作用

    • 量词, 放在一个普通的元字符后面代表出现0-1次 /d?/
    • 取消捕获时候的贪婪, 放在一个量词的元字符后面是取消捕获时候的贪婪性
    • ?: , 在分组捕获时, 只捕获不分组

    match捕获

    字符串中的match方法, 把所有和正则匹配的字符都获取到

    var reg = /d+/g;
    var str = "lemon2020age22";
    var ary = str.match(reg);
    console.log(ary);
    

    ["2020", 22]

    虽然在当前的情况下match比exec更加的简便一些, 但是match中存在一些自己处理不了的问题:

    在分组捕获的情况下, match只能捕获到大正则匹配的内容, 而 对于小正则则捕获的内容是无法获取到的 , 多次捕获到的情况下

    分组引用

    正则分组:

    • 改变优先级
    • 分组引用
    var reg = /^(w)1(w)2$/;
    console.log(reg.test("zzff"));
    console.log(reg.test("z0f_"));
    

    true
    false

    var reg = /(w)1(w)2/g;
    console.log("zzff1bbzz".match(reg));
    console.log("z0f_".match(reg));
    

    2代表和第二个分组出现一模一样的内容; 1和第一个分组出现一模一样的内容;
    一模一样: 和对应的分组中的内容的值都要一样

    分组捕获

    正则在捕获的时候, 不仅仅把大正则匹配的内容捕获到, 而且还可以把小分组匹配的内容捕获到

    var reg = /(d{4})-(d{2})-(d{2})/g
    console.log(reg.exec('2010-12-22') );
    

    ["2010-12-22", "2010", "12", "22"]

    非捕获分组

    var reg1 = /(?:d{4})-(d{2})-(d{2})/g
    reg1.exec('2010-12-22') 
    

    [ "2010-12-22", "12", "22" ]

    在反向引用时,还是通过 um的形式获取前面分组的匹配结果,只不过 在计算第几个分组时不包括非捕获分组

    var reg2 = /(?:d{4})-(d{2})-(d{2})-2/g
    reg2.exec('2010-12-22-22')
    

    [ "2010-12-22-22", "12", "22" ]

    replace

    replace: 把原有的字符替换成新的字符
    在不使用正则的情况下, 每当执行一次只能替换一个字符.

    var str = "lemon2020lemon2021"
    str = str.replace("lemon", "lemonX");
    console.log(str)
    str = str.replace("lemon", "lemonX")
    console.log(str)
    

    "lemonX2020lemon2021"
    "lemonXX2020lemon2021"

    没有实现需求

    使用正则

    var str = "lemon2020lemon2021"
    str = str.replace(/lemon/g, "lemonX");
    

    "lemonX2020lemonX2021"

    replace第一项的值是一个正则它的实现原理

    1. 首先, 我们和exec捕获一样, 把所有和我们正则匹配的都捕获到,
    2. 然后, 把捕获的内容替换成新内容

    /lemon/g, 按照这个正则把str中所有可以匹配的都捕获到, 然后统一都替换成我们的"lemonX"

    str = str.replace(/lemon/g, function(){
        console.log("ok");
        console.log(arguments);
        return "lemonX"
    })
    

    ok

    Arguments { 0: "lemon", 1: 0, 2: "lemonX1XX2020lemonX2XX2021", … }
    ok

    Arguments { 0: "lemon", 1: 13, 2: "lemonX1XX2020lemonX2XX2021", … }

    "lemonXX1XX2020lemonXX2XX2021"

    var reg2 = /(?:d{4})-(d{2})-(d{2})-2/g
    var str2 = '2010-12-22-22 2013-09-11-11'
    str2.replace(reg2, function(){
        console.log("ok");
        console.log(arguments);
        return "1"
    })
    

    ok

    Arguments { 0: "2010-12-22-22", 1: "12", 2: "22", 3: 0, 4: "2010-12-22-22 2013-09-11-11", … }

    ok

    Arguments { 0: "2013-09-11-11", 1: "09", 2: "11", 3: 14, 4: "2010-12-22-22 2013-09-11-11", … }

    "1 1"

    第二个参数换成一个函数

    1. 匿名函数执行多少次, 取决于正则能在字符串中捕获多少次
    2. 每一次执行匿名函数, 里面传递的参数值arguments和我们自己通过exec捕获到的结果是非常类似的(即使正则有分组, 我们同样可以通过arguments获取到分组捕获到内容)
    3. return 你返回的结果是啥, 就相当于把当前这一次大正则捕获的内容替换成你返回的内容
    var str = "2020-9-11";
    var ary = ["零", "壹", "贰", "叁", "肆", "伍", "陆" ,"柒", "捌", "玖"]
    str.replace(/(d)/g, function(){
        return ary[arguments[1]]
    })
    

    "贰零贰零-玖-壹壹"

    arguments[0]: 大正则捕获的
    arguments[1]: 小正则捕获的

    实例

    时间字符串格式化

    var str = "2020-9-11 18:15:00";
    var str2 = "2020/9/11 18:16:00"
    var resStr = "{0}年{1}月{2}日 {3}时{4}分{5}秒"
    var dataArray = str.match(/d+/g)
    resStr.replace(/{(d)}/g, function(){
        return  dataArray[arguments[1]];
    })
    var dataArray2 = str2.match(/d+/g)
    resStr.replace(/{(d)}/g, function(){
        return  dataArray2[arguments[1]];
    })
    

    千分符

    9335673817 9, 335, 673, 817

    var str4 = "9335673817";
    var reg4 = /^(d{1,3})((?:d{3})+)$/
    str4.replace(reg4, function(){
        var result1 = arguments[1];
        var result2 = arguments[2];
        return result1 + "," + result2.replace(/d{3}(?!$)/g, function(){
            return arguments[0] + ","
        })
    })
    

    9, 335, 673, 817

    如果字符串的长度-索引位置本身-1模3 === 0, 则在这个字符串的后面加一个,
    (?!$), 表示不给最后的数字加逗号

    var reg = /d(?!$)/g;
    var str = "175335673817"
    str.replace(reg, function(r, i){
        if( (str.length - i - 1)%3 ===0)
            return r + ",";
        else
            return r
    })
    

    正向预查和负向预查

  • 相关阅读:
    spring security使用数据库管理用户权限
    ubuntu安装配置jdk tomcat mysql ...
    64位虚拟机安装64位ubuntu出现问题
    maven pom文件结构详解
    Maven3下的java web项目
    数据库分页和使用jstl标签替换分页的jsp代码
    servlet生命周期
    图片校验码的生成
    HttpSessionListener和HttpSessionBindingListener监听session的销毁
    perl 处理特殊字符
  • 原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13653802.html
Copyright © 2020-2023  润新知