• js正则表达式


    在线正则测试:http://regexpal.com/

    一点的学习,关于正则的会都放在这里:

    基础知识:

    特殊的元字符/保留字符:正则表达式中不参与匹配的字符,如[],()

    量词:如+,*,?,{3},{3,}里的3,{3,6}

    字符组简写式/转义字符:如d

    捕获分组:用( )括起来,后面可以用1对捕获的内容进行后向引用,如(d)d1匹配三个数字,且第一位和第二位数字相同

    非捕获分组:(?:pattern),匹配pattern但是不保存捕获内容,(?:t|T)(d)1匹配t11而不是t1t

    量词贪心:默认会尽量多的匹配。量词首次尝试匹配整个字符串,若失败则回退一个字符再尝试(这个过程叫回溯),每次回退一个字符直到找到匹配内容或没有字符可以回退了。如a{1,3}会匹配baaab中的aaa;

    量词懒惰/勉强:量词后加?,从目标的起始位置开始寻找匹配,每次检查一个字符,若失败则前进一位直到尝试匹配整个字符串。a{1,3}?会匹配baaab中的a和a和a;

    /.../g: global

    /.../i: ignoreCase

    /.../m: multiline,没有m时,整个目标文本被当作一个字符串,^只匹配最开始的一个地方,/.../m时,^匹配每一行的开始。

    /.../gsm: s:表示.除了匹配其他字符外,还匹配换行符

    [1-3]

    [369]

    [,;]

    d,D

    [^0-9]

    w,w

    s,S

    

    B

    .

    {3}

    ?

    |:注意a|bc和(a|b)c的区别

    ^

    $

    1、关于

    :匹配一个单词边界,除了空格外,“-”、“/”、“.”、“;”、“,”、“《”等标点符号都被当做单词边界(下划线‘_'不能界定边界),

    如'ab_c-d;8<e f.g/h'.replace(/(w)/g, '0$1')的结果是:ab_c-0d;08<0e 0f.0g/0h  (注意最后一个h也被替换了,因为最开头和最后面默认有一个边界);

    又如把2009-8-5转换成2009-08-05,可以‘2009-8-5'.replace(/(d)/g, '0$1')=='2009-08-05'

    2、关于B

    B:匹配非单词边界。

    "123456789".replace(/d{3}B/g,function(s){return s+',';});------"123,456,789"
    "123456789".replace(/Bd{3}/g,function(s){return s+',';});------"1234,567,89";

    3、关于^和$

    这两个分别匹配字符串的开始位置和结束位置。如/4$/表示要以4结尾;/^4$/则只匹配4,像434不匹配。

    4、关于匹配汉字

    /[u4e00-u9fa5]/表示匹配汉字,如把字符串a中所有汉字换成’-‘:a.replace(/[u4e00-u9fa5]/g,'-');检验字符串a中是否全是汉字:不是/^[u4e00-u9fa5]$/.test(a);这只会匹配一个汉字,应该是/^[u4e00-u9fa5]+$/.test(a);

    5、关于$1...$9

    RegExp对象的$1...$9属性是只读的,如果表达式模式中有括起来的子匹配,$1…$9属性值分别是第1个到第9个子匹配所捕获到的内容。如果有超过9个以上的子匹配,$1…$9属性分别对应最后的9个子匹配。如/^(d{3,4})-(d+)$/.test('079-8778');alert(RegExp.$1);alert(RegExp.$2);分别为079和8779.

    如实现一个如下功能的函数:把1转换成‘1’,把1转换成‘12’,把1转换成‘12’,把1转换成‘123’,把1转换成‘123’,把1234转换成‘1,234’,把12345转换成‘12,345’,......把12345678转换成‘12,345,678’, 

    function groupByCommas(n) {
      var n=n.toString();
      if((n.length<7)&&(n.length>3)) return n.replace(/(d{3}$)/g,",$1");
      else{
        switch(n.length%3){
          case 1:  return n.replace(/(^d{1})(d{3}B)/g,"$1,$2,");
          case 2:  return n.replace(/(^d{2})(d{3}B)/g,"$1,$2,");
          default: return n.replace(/(^d{3})(d{3}B)/g,"$1,$2,")
        }
      }
    }

     上面这种做法不对的,会把1234567890转换成‘1,234,567890’,下面的正确。

    function groupByCommas(n) {
      var n=n.toString();
      if(n.length<3) return n;
      else{
        switch(n.length%3){
          case 1:  return n.replace(/(^d{1})/g,"$1,").replace(/(d{3}B)/g,"$1,");
          case 2:  return n.replace(/(^d{2})/g,"$1,").replace(/(d{3}B)/g,"$1,");
          default: return n.replace(/(d{3}B)/g,"$1,")
        }
      }
    }

     更好更简洁的方法如下:

    function groupByCommas(n) {
      return n.toString().replace(/B(?=(d{3})+(?!d))/g, ",");
    }

    Bxxx表示xxx不是在边界开始的地方;

    +表示重复至少一次;

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

    d表示0-9中的任意一个;

    {3}表示重复3次;

    (?=xxx)表示前面字符的右边必须匹配xxx,可以理解为这只是这个缝隙的后面要匹配的内容,不影响xxx继续匹配正则表达式后面的内容。

    如/window(?=NT|XP)/g只匹配'windowNTwindow7'中的window,而不是匹配windowNT,

    (?!xxx)表示前面字符的右边必须不匹配xxx,同样不影响xxx继续匹配正则表达式后面的内容。

    综上,/B(?=(d{3})+(?!d))/g表示一个缝隙,不是单纯开始的缝隙,此缝隙右边必须有3个数字(这3个数字可以出现一次或多次),接着不能出现数字,也就是缝隙右边只能出现3的倍数个数字。

    或者

    str.replace(/(d)(?=(d{3})+(.d+)?$)/g,'$1,')

    /(d)(?=(d{3})+(.d+)?$)/g表示匹配一个数字,这个数字后面要么的多组d{3}结尾要么是多组d{3}后跟着一个小数点和多位数字结尾。

    或者

    str..replace(/B(d{3})(?=(d{3})*(.d+)?$)/g,',$1')

    /B(d{3})(?=(d{3})*(.d+)?$)/gb表示匹配一个三位数字,且不是最开头的三位数字,这三位数字后面要么啥也没有,要么后面是0组或多组d{3},然后以一个小数点和多位数字结尾或是直接结尾。

    补充内容:贪婪模式和非贪婪模式

    如对于字符串“dxxxdxxxd”

    /d(w+)d/匹配完整的“dxxxdxxxd”,/d(w+?)d/匹配完整的“dxxxd”。

    贪婪模式:匹配次数尽可能多,

    非贪婪模式:当在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式。

    常用正则表达式:

    只允许字母和空格: /^[a-zA-Z ]*$/
    e-mail: /([w-]+@[w-]+.[w-]+)/
    url: /(?:(?:https?|ftp)://|www.)[-a-z0-9+&@#/%?=~_|!:,.;]*[-a-z0-9+&@#/%=~_|]/i

    计算匹配项出现的次数: 

    //注意是全局模式//g
    var p=/.cc/g,fullText='aaccbbccddcc';
    p.exec(fullText);
    //["acc"]
    p.lastIndex;
    //4
    p.exec(fullText);
    //["bcc"]
    p.lastIndex;
    //8
    p.exec(fullText);
    //["dcc"]
    p.lastIndex;
    //12
    p.exec(fullText);
    //null
    p.lastIndex;
    //0
    p.exec(fullText);
    //["acc"]
    ......

    所以计算次数为:

    var count=0;
    while(p.exec(fullText)){count++;}
    return count;

    如果希望对字符串'bbaaacc'匹配'aa'的次数为3,则:

    var count=0,searchText='aa',fullText='baaa';
    var p=new RegExp(searchText,'g');//在正则表达式中引入变量的方法
    while(p.exec(fullText)){p.lastIndex-=searchText.length-1;count++;}
    return count;

     .replace(/.../,...)

    $& Inserts the matched substring.
    $` Inserts the portion of the string that precedes the matched substring.
    $' Inserts the portion of the string that follows the matched substring.

    例如:

    'dabc'.replace(/a/,'11$&')--------"d11abc"

    'dabc'.replace(/a/,'11$`')--------"d11dbc"

    'dabc'.replace(/a/,"11$'")--------"d11bcbc"

    也可以.replace(reg, function), function参数为(match, $1, $2,...)

    如: 'a-bc-de'.replace(/[-_](w)/g,(match,$1)=>{console.log(match);return $1.toUpperCase()})   // 'aBcDe'

  • 相关阅读:
    DjangoContenttype
    高并发的详解及解决方案
    Django之路由系统
    Django之ORM
    Django form表单
    AJAX
    python之协程
    python八大排序算法
    python之路-进程
    网络基础
  • 原文地址:https://www.cnblogs.com/yigeqi/p/4031393.html
Copyright © 2020-2023  润新知