• JavaScript正则表达式,这一篇足矣


    正则表达式

    正则表达式(regular expression)是一个描述字符模式的对象。
    ECMAScript的RegExp类表示正则表达式。
    而string和RegExp都定义了使用正则表达式进行强大的模式匹配和文本检索与替换的函数。

    简单的模式可以是一个单独的字符。a
    更复杂的模式包括了更多的字符,并可用于解析、格式检查、替换等等。
    您可以规定字符串中的检索位置,以及要检索的字符类型,等等。

    正则表达式只是一个字符串。没有长度限制,但是,这样的正则表达式长度往往较短。如下所示是一些正则表达式的例子:

    I had a \S+ day today
    [A-Za-z0-9\-_]{3,16}
    \d\d\d\d-\d\d-\d\d
    v(\d+)(\.\d+)*
    TotalMessages="(.*?)"
    ]>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    这些字符串实际上都是微型计算机程序。
    正则表达式的语法,实际上是一种轻量级、简洁、适用于特定领域的编程语言。

    创建正则表达式

    • 使用字面量创建:var re = /a/
    • 使用RegExp构造函数创建:var re = new RegExp(“a”,“修饰符”);
    • g 全局 从头查找到尾部
    • i 不区分大小写
    • m 支持换行操作
    var reg=new RegExp("a","g");
    console.log(reg.flags);//修饰符
    console.log(reg.source);//正则内容
    
    • 1
    • 2
    • 3

    正则表达式对象的方法

    方法功能
    test()返回一个布尔值,方法用于匹配字符串,匹配成功返回true,失败返回false
    exec()方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。
    var reg=/a/g;
    
    console.log(reg.test("abac"));
    console.log(reg.test("abac"));
    console.log(reg.test("abac"));//false
    console.log(reg.test("abac"));//重新从第一个开始查找
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:

    在一个正则对象使用test或者exec时,如果使用全局查找,将自动记录查找指针,同一个正则对象再次查找指针会继续上次的位置开始向后查找
    exec 使用全局g无效 一次无法全部找到,多次可以使用全局g

    常用字符串匹配的正则方法

    方法功能
    replace()用于替换,接受两个参数,第一个是匹配项,第二个可以是字符串或是一个函数
    match()接受一个参数,正则去匹配字符串,如果匹配成功,就返回匹配成功的数组,如果匹配不成功,就返回null
    search()参数与match相同,返回字符串中第一个匹配项的索引,没有匹配项返回-1
    Split()把字符串分割为字符串数组。

    找见某一个字符并换掉

    var str="abcdefB";
    str=str.replace(/c/,"z");
    console.log(str);//abzdefB
    
    • 1
    • 2
    • 3

    全局 从头查找到尾部

    str=str.replace(/b|e/g,"z");//(或)全局  从头查找到尾部
    console.log(str);
    str=str.replace(/b|e/gi,"z");//i 不区分大小写
    
    • 1
    • 2
    • 3

    替换

    var str='{"a":1,"b":2,"c":3}';
    str=str.replace(/"/g,"'");
    console.log(str)
    //{'a':1,'b':2,'c':3}
    
    • 1
    • 2
    • 3
    • 4

    search在使用g时无效

    console.log("abacad".search(/a|d/g))
    //0
    
    • 1
    • 2

    match 查找内容

    console.log("abacad".match(/a|d/g));
    ['a', 'a', 'a', 'd']
    
    • 1
    • 2

    可以使用正则表达式多种符号切割字符

    console.log("a-b-c".split("-"));//['a', 'b', 'c']
    console.log("a=b-c".split(/=|-/));//['a', 'b', 'c']
    
    • 1
    • 2

    替换

    var str="abacad".replace(/c|d/g,"z");
    console.log(str);//abazaz
    
    • 1
    • 2

    replace不但可以查找一个,通过正则表达式可以查找多个,也可以替换为不同的内容

    var i=0;
    var str="abacad".replace(/c|d/g,function(item,index,str){
    	console.log(item,index,str);
    	i++;
    	return i;
    })
    console.log(str)//aba1a2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    var str = "abc345hh67";
    var reg = /\d{2}/;
    
    console.log(str.match(reg));//['34', index: 3, input: 'abc345hh67', groups: undefined]
    console.log(str.search(reg));//3
    console.log(str.replace(reg,"哈哈哈哈"));//abc哈哈哈哈5hh67
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    元字符

    修饰符

    修饰符功能
    i执行对大小写不敏感的匹配。
    g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
    m执行多行匹配。

    字符匹配

    正则表达式中包含了一系列的字符,这些字符只能匹配它们本身。有一些被称为“元字符”的特殊字符,可以匹配一些特殊规则。
    如下所示的例子中,我用蓝色标出了元字符。
    I had a \S+ day today
    [A-Za-z0-9\-_]{3,16}
    \d\d\d\d-\d\d-\d\d
    v(\d+)(\.\d+)*
    TotalMessages="(.*?)"
    ]*> 
    
    大部分的字符,包括所有的字母和数字字符,是普通字符。也就意味着,它们只能匹配它们自己。例如:
    cat
    意味着,只能匹配一个字符串,以“c”开头,然后是字符“a”,紧跟着是字符“t”的字符串
    不做特殊说明,正则表达式中是区分大小写的。但是,几乎所有正则表达式的实现,都会提供一个Flag用来控制是否区分大小写。
      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    点通配符

    • 这是我们第一个讲解的元字符,“.”相当于CSS中*,它意味着可以匹配所有的字符,称之为通配符。
    • /c.t/ 就是第一个字符是c,第二个字符是任意字符,第三个字符是t。注意如果ct,或者coot是不符合规则的。
    • /c\.t/ 如果用\. 来描述,.在这里就不是通配符了,而是表示第一个字符是c,第二个字符是.,第三个字符是t
    • 这里的反斜杠其实也是元字符,表示把一些元字符恢复到原来的字符功能。

    注意:在元字符中.不能用于 匹配换行符,因为换行符在不同的表示方法中实现不同。

    方括号范围匹配

    只有满足[ ]任意一个字符
    字符类是一组在方括号中的字符【a-z】【A-Z】【0-9】
    例如

    • c[aeiou]t 第一个字符是c,第二个字符可以是a,e,i,o,u中的任意一个字符,第三个字符是t。
    • [012345679] 匹配数字中除了8以外的任意一个整数
    • [a]匹配单一字符a
    • [\[\]\ab] 仅匹配一个字符,[ 意味着匹配“[”,]意味着匹配“]”,\ab,意味着匹配一个a或者b的字符。
    • [\\\[\]] ???这是什么
    console.log('\\[]'.match(/\\\[\]/));// 输出:['\\[]', index: 0, input: '\\[]', groups: undefined]
    console.log('\\[]');//  输出:\[]
    
    • 1
    • 2
    • [dabaaabcc] 注意这里出现了重复和顺序问题,这种写法其实没有任何意义,与[abcd]相同
    • [.] 这种元字符是匹配.,与.单独出现是不同的。他表示必须匹配一个字符全角字符句号,与单独出现与.的作用也不相同,后者是一个.字符。/[.]/ 代表字符. 不是通配符
    • 字符类描述的过程中可以省略中间值,用-直接连接首尾,例如[a-z]a-z的所有字符,[f-z]f-z的所有字符
    • [1-9]1,2,3,4,5,6,7,8,9
    • [A-Z]大写的A到Z的所有字符匹配
    • [0-9.,]匹配0到9的任意数字或者全角句号或者逗号
    • [0-9A-F]匹配0到9的任意数字或者大写A到大写F的任意字符
    • [0-9a-z\-] 匹配0-9,a-z的任意数组或者字符,或者-字符
    • 一般我们用[]这种字符类匹配是为了在匹配是某些字符可以是多个字符。所以单独使用[a]a是一样的作用。

    错误提示
    即使[A-z]在你使用的实现中,是合法的,也可能会产生无法预料的运行结果。

    [1-31] 这是什么??123还是1-31[1-31] 匹配的是123中的某一项
    
    • 1
    • 2
    console.log(/[{}]/);//匹配{ 和 }任意一个字符
    
    • 1

    方括号字符反义

    [^]反义字符,表示除了^所描述的字符外的其他字符,类似于js中!的作用。
    [^a]
    [^a-zA-Z0-9]
    [\^abc]
    [^\^]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    转义字符类

    项目Value
    \w查找单词字符。与[a-zA-Z_0-9]相同
    \W查找非单词字符。[^0-9A-Za-z_]相同
    \d查找数字。与[0-9]相同
    \D查找非数字字符。与[^0-9]相同
    \s查找空白字符。
    \S查找非空白字符。
    \b单词分割符
    \B非单词分割符

    用空格切割

    console.log("ab cd ef".split(/\s/));//用空格切割
    // ['ab', 'cd', 'ef']
    
    • 1
    • 2

    用非空格匹配后的字符数组转为字符串

    console.log(" aja ajsn  asd  assd a a sa asd ".match(/\S/g).join(""));
    
    • 1

    重复匹配

    m{n} 表示m重复n次

    console.log(/1[3-9]\d\d\d\d\d\d\d\d\d/.test("13890876890"))
    console.log(/1[3-9]\d{9}/.test("13890876890"))
    
    • 1
    • 2

    普通重复

    console.log(/ab{3}/)  //abbb
     console.log(/(ab){3}/) //ababab
     console.log(/a{1}/)// 等价与/a/
     console.log(/a{0}/)// 匹配""字符
    
    • 1
    • 2
    • 3
    • 4
    console.log(/\d\d\d\d-\d\d-\d\d/)
    console.log(/\d{4}(-\d{2}){2}/)
    
    • 1
    • 2

    重复次数范围+贪婪匹配

    {最低,最多}

    console.log("caab".match(/ca{3,8}b/))//null
    console.log("caaab".match(/ca{3,8}b/))
    console.log("caaaaaaaab".match(/ca{3,8}b/))
    console.log("caaaaaaaaab".match(/ca{3,8}b/))//null
    
    • 1
    • 2
    • 3
    • 4
    console.log("a1231241231b".match(/a\d{1,20}b/));
    console.log("a1b".match(/a\d{0,20}b/));//可以是:"ab","a1b";
    
    • 1
    • 2
    //任意字符一位或者40位之间
    console.log("a1283712387basvad18927318273v".match(/a.{1,40}v/g));//['a1283712387basvad18927318273v']
    console.log("aaaaaaaa".match(/a{3,5}/g));// ['aaaaa', 'aaa']
    
    
    • 1
    • 2
    • 3
    • 4

    不给最大值,表示无穷大(0个也好,无数也罢)

    console.log("aaaaaaaaa".match(/a{0,}/g));//不给最大值,表示无穷大
    
    • 1

    几种不同的取值情况

    console.log("a".match(/a{0,}/g));
    //['a', '']
    console.log("a".match(/a{0}/g));
    //['', '']
    console.log("a".match(/a{1}/g));
    //['a']
    console.log("colour".match(/colou{0,1}r/g));
    //可有可无
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    所以就有了几种简写模式

    {0,} _ *0个也好,无数也罢
    {1,} _ +整一个及以上
    {0,1} _可有可无

    非贪婪匹配

    .字符后面有*?或者+?通通称之为非贪婪匹配;

    console.log("av1283712387basvad18927318273v".match(/a.+?v/g));
    // ['av1283712387basv', 'ad18927318273v']
    console.log("av1283712387basvad18927318273v".match(/a.*?v/g));
    // ['av', 'asv', 'ad18927318273v']
    console.log("中国的四大名著包括《西游记》、《三国演义》、《水浒传》、《红楼梦》".match(/《.+?》/g))
    //['《西游记》', '《三国演义》', '《水浒传》', '《红楼梦》']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    var str = "

    Uber的这款无人车原型配备了多个摄像头激光雷达以及传感器,可看清100米范围内任何方向的东西


    第二行内容,哎嘿,第二行内容

    "
    ; str=str.replace(/<.+?>/g,function(item){ return item==="
    "
    ? "\n" : ""; })
    • 1
    • 2
    • 3
    • 4
    • 5

    起始和结束符

    项目Value
    ^ 起始正则表达式开始的位置加入这个表示整个字符串必须以这个字符起始
    /^a/必须以a作为开始
    $结束正则表达式结束的位置加入这个表示整个字符串必须以这个字符结束
    /a$/必须以a结束
    • 如果使用^和$ 可以约束整个字符串的长度限制
    • 必须把^ 写在第一位处理
    console.log(/^ab$/.test("ab"))//true
    console.log(/b.{4}$/.test("asdhjasdbaaaa"));//匹配后几位是b的结尾
    
    • 1
    • 2

    | 或者

    注意:如果这里的写两个||表示对空字符也会做一个匹配
    如果匹配成功,不会进行后面正则判断

    console.log(/cat|dog/.test("dog"));
    console.log(/cat|dog/.test("cat"));
    
    console.log("abacad".match(/ab||ac/g));
    console.log("abacad".match(/ab|ac|/g));
    console.log("abacad".match(/|ab|ac/g));
    
    true
    true
    ['ab', '', '', '', '', '']
    ['ab', 'ac', '', '', '']
    ['', '', '', '', '', '', '']
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    /a|b/ 等价于 [a|b]
    
    • 1

    案例锦集:

    匹配1-31

    /^[1-9]$|^[12]\d$|^3[01]$/
    
    • 1

    匹配0-255

    /^\d$|^[1-9]\d$|^1\d{2}$|^2[0-4]\d$|^25[0-5]$/
    
    • 1

    匹配IP地址

    0.0.0.0-255.255.255.255
    /^(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])(\.(\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])){3}$/
    
    • 1
    • 2

    群组

    1. ( )可以将部分正则内容作为一组使用
    2. 可以筛选出字符串中符合需求的部分
    3. 将括号里的东西放在这个获取数组的后面部分

    例如:

    var str="3";
    console.log(str.match(/(\d+)<([a-zA-Z]+)>/))
    
    • 1
    • 2

    网址正则

    var str="http://www.163.com/news/a/b/index.html";
    console.log(str.match(/(https?:)\/\/([^\/]+)(.+\/)(.*)/));
    
    • 1
    • 2

    match不允许群组的全局查找

    群组の替换

    var str="3[ab]12[cd]";
    str=str.replace(/(\d+)\[([a-zA-Z]+)\]/g,function(item,a,b){
        // console.log(item,a,b);
            return b.repeat(a);
    });
    console.log(str)
    //abababcdcd
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    群组替换,对象赋值

    var str="a=3&b=a&c=5&d=6";
    var o={};
    str.replace(/(\w+)=([^&]+)/g,function(item,a,b){
        o[a]=isNaN(b) ? b : Number(b);
    })
    console.log(o)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    群组替换

    var str="18617890567";
    // 群组1  $1
    // 群组2  $2
    str=str.replace(/(\d{3})\d{4}(\d{4})/,"$1****$2");
    console.log(str);
    186****0567
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    var str="11012219980524401X";
    str=str.replace(/(\d{4})\d{11}(\d{3}|\d{2}X)/,"$1***********$2");
    console.log(str);
    1101***********01X
    
    • 1
    • 2
    • 3
    • 4
    面试题
    var str="3[2[a]3[bc]]2[ab]";
    
    function stringify(str){
        if(!/\d+\[\w+\]/.test(str)) return str;
        return stringify(str.replace(/(\d+)\[(\w+)\]/g,function(item,a,b){
            return b.repeat(a);
        }));
    }
    str= stringify(str);
    console.log(str)
    
    aabcbcbcaabcbcbcaabcbcbcabab
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    断言

    后置肯定断言?=n

    判断a的后面是不是d,如果是则替换这个a
    var str="abadae";
    console.log(str.replace(/a(?=d)/g,"0"));
    //ab0dae
    
    • 1
    • 2
    • 3
    • 4

    后置否定断言 ?!n

    判断a的后面是除了d的a之外的所有a被替换
    var str="abadae";
    console.log(str.replace(/a(?!d)/g,"0"));
    //0bad0e
    
    • 1
    • 2
    • 3
    • 4

    前置肯定断言 ?<=n

    看箭头指向,b的前面是c的这样的b,被替换
    var str="abcbdb";
    console.log(str.replace(/(?<=c)b/g,"0"))
    //abc0db
    
    • 1
    • 2
    • 3
    • 4

    前置否定断言 ?

    判断b前面是除了c的a之外的所有b被替换0
    var str="abcbdb";
    console.log(str.replace(/(?/g,"0"))
    a0cbd0
    
    • 1
    • 2
    • 3
    • 4

    "3+5="-->"3+5=8"面试题

    var str="1+2+3=";
    str=str.replace(/(?<=\=)/,function(item,index,str){
         return str.match(/(\d+)\+(\d+)\+(\d+)/).slice(1).reduce(function(v,t){
            return Number(v)+Number(t);
         })
    })
    console.log(str);    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    高级密码

    (?=\D+\d) 起始字符开始首字母不能是数字,但是在整个字符串中必须包含数字
    (?=.*[a-z]) 在任意位置包含a-z的小写字母
    (?=.*[A-Z]) 在任意位置包含A-Z的大写字母
    [a-zA-Z0-9_-$&!]{8,16} 密码实际包含的字符,要求最少8位,最大16
    • 1
    • 2
    • 3
    • 4
    /^(?=\D+\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9_\-$&!]{8,16}$/
    
    • 1

    中级密码

    console.log(/^(?=\D+\d)(?=.*[a-z])[a-zA-Z0-9_\-$&!]{8,16}$|^(?=\D+\d)(?=.*[A-Z])[a-zA-Z0-9_\-$&!]{8,16}$|^(?=.*[A-Z])(?=.*[a-z])[a-zA-Z0-9_\-$&!]{8,16}$/.test("xietian12"))
    
    • 1

    初级密码

    console.log(/^\d{8,16}$|^[a-z]{8,16}$|^[A-Z]{8,16}$/.test("xietianabc"))
    
    • 1

    重复次数

    (n)\1* 不重复也可以查找到
    (n)\1+ 至少重复1次以上的可以查找到
    n就是正则内容

    输出字符的个数面试题

    var str="hjhjds jksjsdkj alkjd jksdj kswdjli qwdo qijd aksijdais  asdiuaiusd asdiuasdkjh";
    
    var o=str.split("").sort().join("").match(/(.)\1*/g).reduce(function(v,t){
        // console.log(t,t[0],t.length);
        v[t[0]]=t.length;
        return v;
    },{});
    console.log(o)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    变量

    5、变量 (?<变量>筛选的字符)
    把筛选出来的给变量

    var str="3[ab]";
    var reg=/(?\d+)\[(?\w+)\]/g;
    console.log(str.match(/(?\d+)\[(?\w+)\]/).groups)
    //{num: '3', str: 'ab'}
    str.replace(/(?\d+)\[(?\w+)\]/,function(item,a,b,index,str,groups){
    	console.log(groups)
    })
    //{num: '3', str: 'ab'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    增添addClass

    <div class="div1 div2   div3"></div>
    ========================================
    function addClass(elem,className){
    	elem.className=className.match(/\S+/g).reduce(function(v,t){
    	if(!v.includes(t)) v.push(t);
    		return v;
    	},elem.className.match(/\S+/g)).join(" ")
    }
    
    var div=document.querySelector("div");
    addClass(div,"  div2   div4   div5 ")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    删除removeClass

    function addClass(elem,className){
    	elem.className=className.match(/\S+/g).reduce(function(v,t){
    	if(!v.includes(t)) v.push(t);
    		return v;
    	if(v.includes(t)) v.splice(t);//暂存
    	},elem.className.match(/\S+/g)).join(" ")
    }
    
    var div=document.querySelector("div");
    addClass(div,"  div2   div4   div5 ")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    中文查询

    中文匹配
    /[\u4e00-\u9fd5]{2,4}/
    
    • 1
    • 2
  • 相关阅读:
    python使用pysqlcipher3对sqlite数据库进行加密
    vlc将本地文件推流成ts实时流
    动手学深度学习(2)—— 线性神经网络
    分散染料对涤纶织物染色步骤
    一种使用setdll+HOOK钩子技术+dll为MFC程序ProtocalTool等老旧程序打补丁的思路(含源码)
    Linux Shell脚本编写指南
    Pandas-用一个dataframe去更新另一个dateframe
    Java基本数据类型
    (二)docker:建立oracle数据库mount startup
    【软件测试】什么?这是最全的--金融行业测试类型细分,宝藏干G货......
  • 原文地址:https://blog.csdn.net/m0_46672781/article/details/125987000