美文网首页
005.聊聊 JavaScript 正则表达式 上卷

005.聊聊 JavaScript 正则表达式 上卷

作者: 胖先森 | 来源:发表于2017-05-15 10:11 被阅读0次

    假设用户需要在HTML 表单中填写姓名、地址、出生日期等。那么在将表单提交到服务器进一步处理前,JavaScript 程序会检查表单以确认用户确实输入了信息并且这些信息是符合要求的。

    1.什么是正则表达式?

    正则表达式(regular expression)是一个描述字符模式的对象。ECMAScript 的RegExp 类表示正则表达式,而String 和RegExp 都定义了使用正则表达式进行强大的模式匹配和文本检索与替换的函数。
      正则表达式主要用来验证客户端的输入数据。用户填写完表单单击按钮之后,表单就会被发送到服务器,在服务器端通常会用PHP、ASP.NET 等服务器脚本对其进行进一步处理。

    因为客户端验证,可以节约大量的服务器端的系统资源,并且提供更好的用户体验

    2.正则表达式的语法

    1.直接量语法:

     /pattern/attributes;
    

    2.创建RegExp对象的语法

    new RegExp(pattern,attributes);
    

    参数:参数pattern是一个字符串,指定了正则表达式的模式;
    参数attributes是一个可选的参数,包含属性 g,i,m,分别使用与全局匹配,不区分大小写匹配,多行匹配;
    @return 返回值:一个新的RegExp对象,具有指定的模式和标志;

    g,i,m说明图

    3.支持正则表达式的String对象的方法

    (1) search()方法;

    该方法用于检索字符串中指定的子字符串或检索与正则表达式相匹配的字符串。

    基本语法: stringObject.search(regexp);

    • @param : 参数regexp可以需要在stringObject中检索的字符串,也可以 是需要检索的RegExp对象。
    • @return(返回值) : stringObject中第一个与regexp对象相匹配的子串的起始位置。如果没有找到任何匹配的子串,则返回-1;

    注意:search()方法不执行全局匹配,它将忽略标志g,同时它也没有regexp对象的lastIndex的属性,且总是从字符串开始位置进行查找,总是返回的是stringObject匹配的第一个位置

    测试代码

    var str = "hello world,hello world";
    // 返回匹配到的第一个位置(使用的regexp对象检索)
    console.log(str.search(/hello/)); // 0
    // 没有全局的概念 总是返回匹配到的第一个位置
    console.log(str.search(/hello/g)); //0
    
    console.log(str.search(/world/)); // 6
    
    // 也可以是检索字符串中的字符
    console.log(str.search("wo")); // 6
    
    // 如果没有检索到的话,则返回-1
    console.log(str.search(/longen/)); // -1
    
    // 我们检索的时候 可以忽略大小写来检索
    var str2 = "Hello";
    console.log(str2.search(/hello/i)); // 0
    

    (2) match()方法

    该方法用于在字符串内检索指定的值,或找到一个或者多个正则表达式的匹配。该方法类似于indexOf()或者lastIndexOf(); 但是它返回的是指定的值,而不是字符串的位置;

    基本语法:stringObject.match(searchValue) 或者 stringObject.match(regexp)

    • @param(参数)
       searchValue 需要检索字符串的值;
       regexp: 需要匹配模式的RegExp对象;
    • @return(返回值) : 存放匹配成功的数组; 它可以全局匹配模式,全局匹配的话,它返回的是一个数组。如果没有找到任何的一个匹配,那么它将返回的是null;返回的数组内有三个元素,第一个元素的存放的是匹配的文本,还有二个对象属性;index属性表明的是匹配文本的起始字符在stringObject中的位置;input属性声明的是对stringObject对象的引用;

    测试代码:

    var str = "hello world";
    console.log(str.match("hello")); // ["hello", index: 0, input: "hello world"]
    console.log(str.match("Hello")); // null
    console.log(str.match(/hello/)); // ["hello", index: 0, input: "hello world"]
    // 全局匹配
    var str2="1 plus 2 equal 3"
    console.log(str2.match(/\d+/g)); //["1", "2", "3"]
    

    (3) replace()方法

    该方法用于在字符串中使用一些字符替换另一些字符,或者替换一个与正则表达式匹配的子字符串;

    基本语法:stringObject.replace(regexp/substr,replacement);

    • @param(参数)
       regexp/substr; 字符串或者需要替换模式的RegExp对象。
       replacement:一个字符串的值,被替换的文本或者生成替换文本的函数。
    • @return(返回值) 返回替换后的新字符串

    注意:字符串的stringObject的replace()方法执行的是查找和替换操作,替换的模式有2种,既可以是字符串,也可以是正则匹配模式,如果是正则匹配模式的话,那么它可以加修饰符g,代表全局替换,否则的话,它只替换第一个匹配的字符串;

    • replacement : 既可以是字符串,也可以是函数,如果它是字符串的话,那么匹配的将与字符串替换,replacement中的$有具体的含义

    1,1,2,3....3....99 含义是:与regexp中的第1到第99个子表达式相匹配的文本

    $& 的含义是:与RegExp相匹配的子字符串。
    var str = "hello world";
    // 替换字符串
    var s1 = str.replace("hello","a");
    console.log(s1);// a world
    // 使用正则替换字符串
    var s2 = str.replace(/hello/,"b");
    console.log(s2); // b world
    
    // 使用正则全局替换 字符串
    var s3 = str.replace(/l/g,'');
    console.log(s3); // heo word
    
    // $1,$2 代表的是第一个和第二个子表达式相匹配的文本
    // 子表达式需要使用小括号括起来,代表的含义是分组
    var name = "longen,yunxi";
    var s4 = name.replace(/(\w+)\s*,\s*(\w+)/,"$2 $1");
    console.log(s4); // "yunxi,longen"
    
    // $& 是与RegExp相匹配的子字符串
    var name = "hello I am a chinese people";
    var regexp = /am/g;
    if(regexp.test(name)) {
        //返回正则表达式匹配项的字符串
        console.log(RegExp['$&']);  // am
    
        //返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。
        console.log(RegExp["$'"]); // a chinese people
    
        //返回被查找的字符串从字符串开始的位置到最后匹配之前的位置之间的字符。
        console.log(RegExp['$`']);  // hello I 
        
        // 返回任何正则表达式查找过程中最后括号的子匹配。
        console.log(RegExp['$+']); // 空字符串
    
        //返回任何正则表达式搜索过程中的最后匹配的字符。
        console.log(RegExp['$_']);  // hello I am a chinese people
    }
    
    // replace 第二个参数也可以是一个function 函数
    var name2 = "123sdasadsr44565dffghg987gff33234";
    name2.replace(/\d+/g,function(v){
        console.log(v); 
        /*
         * 第一次打印123
         * 第二次打印44565
         * 第三次打印987
         * 第四次打印 33234
         */
    });
    /*
     * 如下函数,回调函数参数一共有四个
     * 第一个参数的含义是 匹配的字符串
     * 第二个参数的含义是 正则表达式分组内容,没有分组的话,就没有该参数,
     * 如果没有该参数的话那么第四个参数就是undefined
     * 第三个参数的含义是 匹配项在字符串中的索引index
     * 第四个参数的含义是 原字符串
     */
     name2.replace(/(\d+)/g,function(a,b,c,d){
        console.log(a);
        console.log(b);
        console.log(c);
        console.log(d);
        /*
         * 如上会执行四次,值分别如下(正则使用小括号,代表分组):
         * 第一次: 123,123,0,123sdasadsr44565dffghg987gff33234
         * 第二次: 44565,44565,11,123sdasadsr44565dffghg987gff33234
         * 第三次: 987,987,22,123sdasadsr44565dffghg987gff33234
         * 第四次: 33234,33234,28,123sdasadsr44565dffghg987gff33234
         */
     });
    

    (4) split()方法

    该方法把一个字符串分割成字符串数组。

    基本语法如:stringObject.split(separator,howmany);

    • @param(参数)
       1. separator[必填项],字符串或正则表达式,该参数指定的地方分割stringObject;
       2. howmany[可选] 该参数指定返回的数组的最大长度,如果设置了该参数,返回的子字符串不会多于这个参数指定的数组。如果没有设置该参数的话,整个字符串都会被分割,不考虑他的长度。
    • @return(返回值) 一个字符串数组。该数组通过在separator指定的边界处将字符串stringObject分割成子字符串。

    测试代码

    var str = "what are you doing?";
    // 以" "分割字符串
    console.log(str.split(" "));
    // 打印 ["what", "are", "you", "doing?"]
    
    // 以 "" 分割字符串
    console.log(str.split(""));
    /*
     * 打印:["w", "h", "a", "t", " ", "a", "r", "e", " ", "y", "o", "u", " ", "d", "o", "i", "n", 
     * "g", "?"]
     */
    // 指定返回数组的最大长度为3
    console.log(str.split("",3));
    // 打印 ["w", "h", "a"]
    

    4,RegExp对象方法

    (1) test()方法

    该方法用于检测一个字符串是否匹配某个模式;

    基本语法:RegExpObject.test(str);

    • @param(参数) : str是需要检测的字符串;
    • @return (返回值) : 如果字符串str中含有与RegExpObject匹配的文本的话,返回true,否则返回false;

    测试代码

    var str = "longen and yunxi";
    console.log(/longen/.test(str)); // true
    console.log(/longlong/.test(str)); //false
    
    // 或者创建RegExp对象模式
    var regexp = new RegExp("longen");
    console.log(regexp.test(str)); // true
    

    (2) exec()方法

    该方法用于检索字符串中的正则表达式的匹配。

    基本语法:RegExpObject.exec(string)

    • @param(参数):string【必填项】要检索的字符串。
    • @return(返回值):返回一个数组,存放匹配的结果,如果未找到匹配,则返回值为null;

    注意:该返回的数组的第一个元素是与正则表达式相匹配的文本,该方法还返回2个属性,index属性声明的是匹配文本的第一个字符的位置;input属性则存放的是被检索的字符串string;该方法如果不是全局的话,返回的数组与match()方法返回的数组是相同的。

    测试代码

    var str = "longen and yunxi";
    console.log(/longen/.exec(str)); 
    // 打印 ["longen", index: 0, input: "longen and yunxi"]
    
    // 假如没有找到的话,则返回null
    console.log(/wo/.exec(str)); // null
    

    5.正则中的普通字符

    字母,数字,汉字,下划线及一些没有特殊定义的标点符号,都属于普通字符,正则中的普通字符,在匹配字符串的时候,匹配与之相同的字符即可

    代码说明

    var str = "abcde";
    console.log(str.match(/a/)); // ["a", index: 0, input: "abcde"]
    如上代码,字符串abcde匹配a的时候,匹配成功,索引位置从0开始;
    

    6.正则中的方括号[]的含义

    方括号包含一系列字符,能够匹配其中任意一个字符

    (red|blue|green); 查找小括号中的任意一项,小括号中的 | 是或者的意思;
    列举1:表达式[bcd][bcd] 匹配 "abcde"时候,匹配成功,内容是bc,匹配到的位置开始于1,结束与3;
    测试代码

    var str = "abcde";
    console.log(str.match(/[bcd][bcd]/)); // ["bc", index: 1, input: "abcde"]
    

    7.理解javascript中的元字符

    字符类:单个字符和数字

    (1) 元字符 . : 用于匹配任何单个字符(除了换行符以外);
    基本语法:new RegExp(“regexp.”) 或者 直接量语法 /regexp./
    测试代码:

    var str = "abcde";
    console.log(str.match(/a.c/)); // ["abc", index: 0, input: "abcde"]
    

    (2) \w ; 查找任意一个字母或数字或下划线,等价于[A-Za-z0-9_]
    基本语法:new RegExp(“\w”); 或 直接量语法:/\w/
    代码测试:

    var str = "abcde";
    
    // 匹配单个字符,找到一个直接返回
    console.log(str.match(/\w/)); // ["a", index: 0, input: "abcde"]
    
    // 匹配所有字符
    console.log(str.match(/\w+/)); //["abcde", index: 0, input: "abcde"]
    

    (3) \W ; 查找非单词的字符,等价于[^A-Za-z0-9_]
    基本语法:new RegExp(“\W”) 或直接量 /\W/
    代码测试:

    var str = "abcde";
    
    // 匹配单个字符,没有找到返回null
    console.log(str.match(/\W/)); // null
    

    (4) \d : 匹配与一个数字字符,等价于 [0-9];
    基本语法:new RegExp(“\d”); 或 直接量语法:/\d/
    代码测试:

    var str = "abcde111";
    console.log(/\d/g.exec(str)); // ["1", index: 5, input: "abcde111"]
    

    (5) \D : 匹配一个非数字字符,等价于 [^0-9]
    基本语法:new RegExp(“\D”) 或直接量 /\D/
    代码测试:

    var str = "abcde111";
    
    console.log(/\D+/g.exec(str)); // ["abcde", index: 0, input: "abcde111"]
    
    空白字符 锚字符

    (6) \s : 匹配任何空白字符,包括空格,制表符,换行符等等。等价于 [\f\n\r\t\v]
    基本语法:new RegExp(“\s”) 或直接量 /\s/
    代码测试:

    var str="Is this all there is?";
    
    console.log(/\s/g.exec(str)); // [" ", index: 2, input: "Is this all there is?"]
    

    (7) \S : 匹配任何非空白字符,等价于 [^\f\n\r\t\v]
    基本语法:new RegExp(“\S”) 或直接量 /\S/
    代码测试:

    var str="Is this all there is?";
    
    console.log(/\S+/g.exec(str)); // ["Is", index: 0, input: "Is this all there is?"]
    

    (8) \b : 匹配一个单词边界,也就是指单词和空格间的位置,比如’er\b’可以匹配”never”中的”er”,但是不能匹配”verb”中的”er”
    基本语法:new RegExp(“\bregexp”) 或直接量 /\bregexp/
    代码测试:

    var str="Is this all there is?";
    
    console.log(/\bthis\b/g.exec(str)); // ["this", index: 3, input: "Is this all there is?"]
    

    (9) \B : 匹配非单词边界,’er\B’ 能匹配 ’verb’ 中的 ’er’,但不能匹配’never’中的’er’
    基本语法:new RegExp(“\Bregexp”) 或直接量 /\Bregexp/
    代码测试:

    var str="Is this all there is?";
    
    console.log(/\Bhi/g.exec(str)); // ["hi", index: 4, input: "Is this all there is?"]
    

    (10) \n : 匹配一个换行符;返回换行符被找到的位置。如果未找到匹配,则返回 -1。
    基本语法:new RegExp(“\n”) 或直接量 /\n/
    代码测试:

    var str="Is this all \nthere is?";
    
    console.log(/\n/g.exec(str)); // ["换行符", index: 12, input: "Is this all ↵there is?"]
    

    (11) \xxx : 查找一个以八进制数xxx规定的字符,如果未找到匹配,则返回 null。
    基本语法:new RegExp(“\xxx”) 或直接量 /\xxx/
    代码测试:

    var str="Visit W3School. Hello World!";
    
    console.log(/\127/g.exec(str)); // ["W", index: 6, input: "Visit W3School. Hello World!"]
    

    如上代码分析:127的八进制转换为10进制的值等于 18的二次方 + 28的一次方 + 7*8的0次方 = 64 + 16 + 7 = 87 而W的ASCLL编码转换为10进制也是87,因此打印W

    (12) \xdd : 查找以16进制数dd规定的字符。如果未找到匹配,则返回 null。
    基本语法:new RegExp(“\xdd”) 或直接量 /\xdd/
    代码测试:

    var str="Visit W3School. Hello World!";
    
    console.log(/\x57/g.exec(str)); // ["W", index: 6, input: "Visit W3School. Hello World!"]
    

    W的16进制数等于57;

    (13) \uxxxx : 查找以16进制数的xxxx规定的Unicode字符。
    基本语法:new RegExp(“\uxxx”) 或直接量 /\uxxx/
    代码测试:

    var str="Visit W3School. Hello World!";
    
    console.log(/\u0057/g.exec(str)); // ["W", index: 6, input: "Visit W3School. Hello World!"]
    

    8.RegExp特殊字符中的需要转义字符

    • 需要转义的特殊字符前面加 \
    • 匹配输入字符串的结尾位置,如果需要匹配匹配输入字符串的结尾位置,如果需要匹配本身的话,使用$
    • ^ 匹配输入字符串的开始位置,匹配^本身的话,使用 \^
    • * 匹配前面的子表达式的零次或者多次,匹配*本身的话,使用 \*
    • +匹配子表达式的1次或者多次,匹配+本身的话,使用 \+
    • . 匹配除换行符之外的任何一个字符,匹配.本身的话,使用 \.
    • [ 匹配一个中括号开始,匹配本身的,使用 \[
    • ? 匹配前面的子表达式的零次或者1次,或指明一个非贪婪限定符,要匹配本身的话,使用 \?
    • \ 匹配本身的话,请使用\\\\
    • { 标记限定符开始的地方,要匹配{ ,请使用 \{
    • | 指明多项中的一个选择,可以理解含义为或的意思,匹配本身的话,使用 \|

    9.了解量词

    了解量词
    (1) n+ 匹配至少包含一个或者多个n的字符串。
    基本语法:new RegExp(“n+”) 或直接量 /n+/
    测试代码:
    var str = "hello longen";
    
    // 匹配至少一个或者多个l的字符串
    
    console.log(str.match(/l+/g)); //["ll", "l"]
    
    // 匹配至少一个或者多个字母数字或者下划线
    
    console.log(str.match(/\w+/g)); //["hello", "longen"]
    

    (2) n 匹配零个或者多个n的字符串。
    基本语法:new RegExp(“n*”) 或直接量 /n*/
    测试代码:

    var str = "hello longen hello";
    
    // 匹配至少零个或者多个l的字符串 
    
    // 可以匹配多个l或者不匹配l 全局匹配
    
    console.log(str.match(/el*/g)); //["ell", "e", "ell"]
    
    // 可以匹配多个u或者不匹配u 全局匹配
    
    console.log(str.match(/hu*/g)); //["h", "h"]
    

    (3) n? 匹配零个或者1个n的字符串,可以匹配n字符串,也可以只匹配一个n;先尽量匹配,如没有匹配到,就回溯,再进行不匹配;
    基本语法:new RegExp(“n?”) 或直接量 /n?/
    测试代码:

    var str = "hello longen hello";
    
    // 匹配至少零个或者1个l的字符串 
    
    console.log(str.match(/el?/g)); //["el", "e", "el"]
    
    // 可以匹配1个u或者不匹配u 全局匹配
    
    console.log(str.match(/hu?/g)); //["h", "h"]
    

    (4) n{x} 匹配包含x个的n的序列字符串。X必须是数字。
    基本语法:new RegExp(“n{x}”) 或直接量 /n{x}/
    测试代码:

    var str="100, 1000 or 10000?";
    
    // 匹配4个数字的 匹配到1000和10000
    
    console.log(str.match(/\d{4}/g)); //["1000", "1000"]
    

    (5) n{x,y} 匹配包含至少x个的n字符串,最多y个n字符串。
    基本语法:new RegExp(“n{x,y}”) 或直接量 /n{x,y}/
    测试代码:

    var str="100, 1000 or 10000?";
    
    // 匹配最小3个数字,最多四个数字的 匹配到100,1000和10000
    
    console.log(str.match(/\d{3,4}/g)); //["100", "1000", "1000"]
    

    (6) n{x,} 匹配至少包含x个n序列的字符串;
    基本语法:new RegExp(“n{x,}”) 或直接量 /n{x,}/
    测试代码:

    var str="100, 1000 or 10000?";
    
    // 匹配最小3个数字 匹配到100,1000和10000
    
    console.log(str.match(/\d{3,}/g)); //["100", "1000", "1000"]
    

    (7) n$ 匹配任何以n结尾的字符串
    基本语法:new RegExp(“n$”) 或直接量 /n$/
    测试代码:

    var str="my name is longen";
    
    // 匹配以en结尾的字符串
    
    console.log(str.match(/en$/g)); //["en"]
    

    (8) ^n 匹配任何以n开头的字符串;
    基本语法:new RegExp(“^n”) 或直接量 /^n/
    测试代码:

    var str="my name is longen";
    
    // 匹配以my开头的字符串
    
    console.log(str.match(/^my/g)); //["my"]
    
    // 匹配以na开头的字符串,没匹配到,返回null
    
    console.log(str.match(/^na/g)); //null
    

    (9) ?=n 匹配任何其后紧接指定字符串n的字符串;
    基本语法:new RegExp(“regexp(?=n)”) 或直接量 /regexp(?=n)/
    测试代码:

    var str="my name is longen";
    
    // 匹配以na其后紧接m的字符串
    
    // ?= 只是匹配位置,不会返回值
    
    console.log(str.match(/na(?=m)/g)); //["na"]
    

    (10) ?!n 匹配任何其后不紧接n的字符串 基本语法:new RegExp(“regexp(?!n)”)或直接量/regexp(?!n)/`
    测试代码:

    var str="my name is longen";
    
    // 匹配以na其后不紧接ma的字符串
    
    // ?! 只是匹配位置,不会返回值
    
    console.log(str.match(/na(?!ma)/g)); //["na"]
    
    console.log(str.match(/na(?!m)/g)); // null
    

    (11) ^ 以字符串开始的地方匹配,不匹配任何字符;
    比如:表达式^aaa 在匹配字符串 “longen aaa bbb”的时候,匹配的结果是失败的;因为^的含义是以某某字符串开始进行匹配;只有当aaa在字符串起始位置才能匹配成功;比如”aaa longen bbb” 才匹配成功;

    (12) $ 以字符串结束的地方匹配,不匹配任何字符;
    比如:表达式aaa在匹配字符串“longenaaabbb”的时候,匹配的结果是失败的;因为在匹配字符串“longenaaabbb”的时候,匹配的结果是失败的;因为的含义是以某某字符串结束进行匹配;只有当aaa在字符串结束位置才能匹配成功;比如”longen bbb aaa” 才匹配成功;

    (13) \b 匹配一个单词边界,也就是单词与空格之间的位置,不匹配任何字符;
    测试代码:

    var str="my name is longen";
    
    // 匹配单词边界的字符
    
    console.log(str.match(/\bname\b/g)); //["name"]
    
    // 如果不是单词边界的地方,就匹配失败
    
    console.log(str.match(/\blong\b/g)); // null
    

    (14) | 左右两边表达式之间 “或” 关系,匹配左边或者右边。
    测试代码:

    var str = "hello world";
    
    // 使用|的含义是 或者 匹配成功 结果为["hello "] 
    
    //如果再次匹配的话 就是world
    
    console.log(str.match(/(hello | world)/g)); // ["hello "]
    

    (15) ()的含义
    在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰。取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到。

    相关文章

      网友评论

          本文标题:005.聊聊 JavaScript 正则表达式 上卷

          本文链接:https://www.haomeiwen.com/subject/yobcxxtx.html