zoukankan      html  css  js  c++  java
  • 正则表达式总结

    1.关于正则表达式的使用

    网站:https://regexper.com/

    可以去这个网站上将正则表达式表示为形象化的图像

    2.正则表达式研究

    2.1 RegExp对象

    Javascript通过内置对象RegExp支持正则表达式

    有两种方法实例化RegExp对象

    字面量

    构造函数

    字面量的方式

    var reg=/ is /g ;

    如下代码所示

    var reg=/is/;
    'He is a boy.This is a dog. Where is she?'.replace(reg,'IS')
    //"He IS a boy.This is a dog. Where is she?" 
    //只替换了第一个正则匹配的字符
    var reg=/is/g;
    'He is a boy.This is a dog. Where is she?'.replace(reg,'IS')
    //"He IS a boy.This IS a dog. Where IS she?"
    //加上g之后,替换了所有正则匹配到的字符
    

    构造函数

    var reg=new RegExp('is','g');

    构造函数接收2个参数,第1个是正则表达式的文本(这里的要写2次,是因为是特殊字符,如果想使用的话,需要转义),第2个参数是字符串标志

    var reg=new RegExp('\bis\b')
    undefined
    'He is a boy.This is a dog. Where is she?'.replace(reg,'IS')
    //"He IS a boy.This is a dog. Where is she?"
    //只替换了第一个正则匹配的字符
    var reg=new RegExp('\bis\b','g')
    undefined
    'He is a boy.This is a dog. Where is she?'.replace(reg,'IS')
    "He IS a boy.This IS a dog. Where IS she?"
    //加上g之后,替换了所有正则匹配到的字符
    

    修饰符

    g: global 全文搜索,不添加,搜索到第一个匹配停止

    i: ignore case忽略大小写,默认大小写敏感,如下代码所示

    m:multiple lines多行搜索

    'He is a boy.Is he'.replace(/is/g,'0')
    //"He 0 a boy.Is he"
    'He is a boy.Is he'.replace(/is/gi,'0')
    //"He 0 a boy.0 he"
    

    2.2 元字符

    正则表达式由两种基本字符类型组成:

    原义文本字符(例如abc,a)

    元字符 :是在正则表达式中有特殊含义的非字母字符(比如表示单词边界)

    • ? $ ^ . | () {} [] (水平制表符) v (垂直制表符) (换行符) (回车符) (空字符)f(换页符) cX(与X对应的控制字符 Ctrl+X)

    2.3 字符类

    一般情况下正则表达式一个字符对应字符串一个字符

    比如表达式ab 的含义是匹配(ab水平制表符)的字符串

    元字符[]

    但是我们不希望匹配某个字符,还是希望匹配某类字符,这时候怎么处理呢?比如要匹配abc特征的字符

    我们可以使用元字符[] 来构建一个简单的类

    所谓类是指符合某些特性的对象,一个泛指,而不是特指某个字符

    表达式[abc]把字符a或b或c归为一类,表达式可以匹配这类的字符,[abc]的含义就是匹配abc中的一个

    如下代码:[abc]会匹配一个abc中的一个字符,而不是所有的abc字符

    'a1b2c3d4'.replace(/[abc]/g,'X')
    "X1X2X3d4"
    'abc1b2c3d4'.replace(/[abc]/g,'X')
    "XXX1X2X3d4"
    

    字符类取反

    使用元字符^创建反向类/负向类

    反向类的意思是不属于某类的内容

    表达式[^abc]表示不是字符a或b或c的内容

    如下代码

    'abc1b2c3d4'.replace(/[^abc]/g,'X')
    //"abcXbXcXXX"
    

    2.4 范围类

    使用字符串匹配数字[0123456789]

    正则表达式提供了范围类

    所以可以使用[a-z]来连接两个字符表示从a到z的任意字符

    这是个闭区间,也就是包含a和z本身

    如下代码:

    'abc1b2c3d4z9'.replace(/[a-z]/g,'Q')
    //"QQQ1Q2Q3Q4Q9"
    

    在[]组成的类内部是可以连写的 [a-zA-Z],如下:

    'abc1b2c3d4z9AEEEE'.replace(/[a-zA-Z]/g,'Q')
    //"QQQ1Q2Q3Q4Q9QQQQQ"
    

    如果先要匹配-呢

    '2016-09-12'.replace(/[0-9]/g,'A')
    //"AAAA-AA-AA"
    '2016-09-12'.replace(/[0-9-]/g,'A')
    //"AAAAAAAAAA"
    

    2.5 JS预定义类及边界

    正则表达式提供预定义类来匹配常见的字符类

    image-20200709115133114

    匹配一个ab+数字+任意字符的字符串

    ab[0-9][^
    ]
    abd.
    

    边界

    image-20200709142448385

    如下代码:

    'This is a boy'.replace(/is/g,'IS')
    "This IS a boy"
    'This is a boy'.replace(/Bis/g,'IS')
    "ThIS is a boy"
    
    ^不在[]表示以...开始,在[]里面表示取反
    '@122@abc@'.replace(/@./g,'Q')
    //"Q22Qbc@"
    '@122@abc@'.replace(/^@./g,'Q')
    //"Q22@abc@",匹配开头的
    '@122@abc@'.replace(/.@$/g,'Q')
    //"@122@abQ",匹配结尾的
    
    
    '@122@abc@'.replace(/.@$/gm,'Q')
    m可以用来匹配换行的字符串
    

    2.6 量词

    我们希望匹配一个连续出现20次数字的字符串

    dddddddddddddddddd

    字符 描述
    * 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}。
    + 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
    ? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
    {n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。
    {n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。
    {n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。
    d{20}
    表示匹配一个连续出现20次数字的字符串
    
    

    2.7 JS正则贪婪模式与非贪婪模式

    用d{3,6}来匹配12345678的字符串,得到结果是什么呢?是匹配3次,还是6次,还是4,5次呢

    正则表达式在匹配的时候会尽可能多地匹配,直到匹配失败,这是一种贪婪模式

    '12345678'.replace(/d{3,5}/,'Q')
    //"Q678"
    

    如果让正则表达式尽可能少的匹配,也就是说一旦成功匹配不再继续尝试,就是非贪婪模式

    做法很简单,在量词后加上?即可。如下代码,匹配最小匹配到的就可以了。

    '12345678'.match(/d{3,5}?/g)
    //(2) ["123", "456"]
    '123456789'.match(/d{3,5}?/g)
    //(3) ["123", "456", "789"]
    
    '12345678'.replace(/d{3,5}?/g,'X')
    //"XX78"
    

    2.8 分组

    匹配字符串Byron连续出现3次的场景

    Byron{3}表示n重复3次,前面的Byro并没有重复,量词作用于紧挨着的那个单词

    使用() 可以达到分组的功能,使量词作用于分组,上面的需求可以用下面来表示

    (Byron){3}
    
    'a1b2c3d4'.replace(/[a-z]d{3}/g,'X')
    //"a1b2c3d4"
    'a1b2c3d4'.replace(/([a-z]d){3}/g,'X')
    //"Xd4"
    

    使用|可以达到或的效果,Bycon|Casper

    'ByronCasper'.replace(/Byron|Casper/g,'X')
    //"XX"
    'ByronsperByronCasper'.replace(/Byr(on|Ca)sper/g,'X')
    "XByronCasper"
    'ByronsperByrCasper'.replace(/Byr(on|Ca)sper/g,'X')
    //"XX"
    

    反向引用

    2015-12-25=>12/25/2015,使用$来获取分组的内容,如果没有分组的话,将其解读为字符串

    '2015-12-25'.replace(/(d{4})-(d{2})-(d{2})/g,'$2$3$1')
    //"12252015"
    '2015-12-25'.replace(/(d{4})-(d{2})-(d{2})/g,'$1')
    //"2015"
    '2015-12-25'.replace(/(d{4})-(d{2})-(d{2})/g,'$2')
    //"12"
    '2015-12-25'.replace(/(d{4})-(d{2})-(d{2})/g,'$3')
    //"25"
    '2015-12-25'.replace(/(d{4})-(d{2})-(d{2})/g,'$2/$3/$1')
    //"12/25/2015"
    

    忽略分组

    不希望捕获某些分组,只需要在分组内加上 ?: 就可以,如下所示

    (?: Byron) .(ok)

    2.9 前瞻

    正则表达式从文本头部向尾部开始解析,文本尾部方向,成为“前”

    前瞻就是在正则表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反。

    Javacript并不支持后顾

    符合和不符合特定断言成为肯定/正向 匹配和否定/负向匹配

    image-20200709152136410

    w(?=d) 表示匹配到符合单词的而且还要向后面看看是不是数字,匹配部分只算到匹配到的单词部分,不算后面看的部分
    'a2*3'.replace(/w(?=d)/g,'X')
    //"X2*3"
    'a2*34V8'.replace(/w(?=d)/g,'X')
    //"X2*X4X8"
    'a2*34vv'.replace(/w(?=d)/g,'X')
    //"X2*X4vv"
    'a2*34vv'.replace(/w(?!d)/g,'X')
    //"aX*3XXX"
    

    2.10 JS对象属性

    global: 是否 全文搜索,默认false

    ignore case:是否大小写敏感,默认是false

    multiline:多行搜索,默认是false

    lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置

    source:正则表达式的文本字符串

    var reg=/w/;
    reg.global
    //false
    reg.ignoreCase
    //false
    reg.multiline
    //false
    var reg2=/w/gim;
    reg2.global
    //true
    reg2.ignoreCase
    //true
    reg2.multiline
    //true
    
    reg.source
    //"w"
    reg2.source
    //"w"
    
    这几个属性是只读的,不可以手动修改的
    

    2.11 test和exec方法

    RegExp.prototype.test(str)

    用于测试字符串参数中是否存在匹配正则表达式模式的字符串

    如果存在返回true,否则返回false

    var reg=/w/;
    reg.test('a')
    true
    reg.test('$')
    false
    var reg2=/w/gim;
    reg2.test('ab')
    true
    reg2.lastIndex
    1
    reg2.test('ab')
    true
    reg2.lastIndex
    2
    reg2.test('ab')
    false
    reg2.lastIndex
    0
    

    如上代码所示,当使用g的修饰符时候,使用test方法有时返回true,有时返回false,这是因为执行的时候lastIndex会发生变化。

    上面的test方法只知道lastIndex,如果想知道是从哪个字符开始匹配的,要用到

    RegExp.prototype.exec(str)

    使用正则表达式模式对字符串执行搜索,并将更新全局RegExp对象的属性以反映匹配结果

    如果没有匹配的文本则返回null,否则返回一个结果数组

    --index 声明匹配文本的第一个字符的位置

    --input存放被检索的字符串string

    非全局调用

    调用非全局的RegExp对象的exec()时,返回数组

    第一个元素是与正则表达式相匹配的文本

    第2个元素是与RegExpObject的第一个子表达式相匹配的文本(如果有的话)

    第3个元素是与RegExpObject的第二个子表达式相匹配的文本(如果有的话)

    String.prototype.search(reg)

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

    方法返回第一个匹配结果index,查找不到返回-1

    search方法不执行全局匹配,它将忽略标志g,并且总是从字符串的开始进行检索

    'a1b2c3d1'.search('1')
    1
    'a1b2c3d1'.search('10')
    -1
    'a1b2c3d1'.search(1)
    1
    'a1b2c3d1'.search(/1/)
    

    搜索数字也可以得到结果,因为会将数字转换为正则

    String.prototype.match(reg)

    match()方法将检索字符串,以找到一个或多个与regexp匹配的文本

    regexp是否具有标志g对结果影响很大

    非全局调用的情况

    1. 如果regexp没有标志g,那么match()方法就只能在字符串中执行一次匹配
    2. 如果没有找到任何匹配的文本,则返回null
    3. 否则它将返回一个数组,其中存放了与它找到的匹配文本有关的信息
    4. 返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则 表达式的子表达式匹配的文本

    除了常规的数组元素以外,返回的数组还含有2个对象属性

    index声明匹配文本的起始字符在字符串的位置

    input声明对StringObject的引用

    全局调用的情况

    如果regexp具有标志g则match()方法将执行全局检索,找到字符串中的所有匹配子字符串

    没有找到任何匹配的子串,则返回null

    如果找到了一个或多个匹配子串,则返回一个数组

    数组元素中存放的是字符串中所有的匹配子串,而且也没有index属性或input属性

    String.prototype.split(reg)

    我们经常使用split方法把字符串分割为字符数组

    在一些复杂的分割情况下我们可以使用正则表达式解决,如下代码

    'a,b,c,d'.split(',')
    (4) ["a", "b", "c", "d"]0: "a"1: "b"2: "c"3: "d"length: 4__proto__: Array(0)
    'a1b2c3d'.split(/d/)
    (4) ["a", "b", "c", "d"]
    

    String.prototype.replace

    String.prototype.replace(str,replaceStr)

    String.prototype.replace(reg,replaceStr)

    String.prototype.replace(reg,function)

    上面2种方式,上面的例子中已经有体现了,看最后一个方式

    如果想把'a1b2c3d4'=>'a2b3c4d5',用什么方式呢

    function会在每次匹配替换的时候调用,有四个参数:

    1.匹配字符串

    2.正则表达式分组内容,没有分组则没有该参数

    3.匹配项在字符串中的index

    4.原字符串

    如下代码

    'a1b2c3d4e5'.replace(/d/g,function(match,index,origin){
    console.log(index);
    return parseInt(match)+1;
    })
    //1
    //3
    //5
    //7
    //9
    "a2b3c4d5e6"
    

    还可以用下面的分组参数

    'a1b2c3d4e5'.replace(/(d)(w)(d)/g,function(match,group1,group2,group3,index,origin){
    console.log(match);
    return group1+group3;
    });
    //1b2
    //3d4
    "a12c34e5"
    
  • 相关阅读:
    从代码书写理解指针,很重要
    指针参数 引用参数
    [转载]c/c++ 操作sqlite
    [转载]C#.NET DataTable扩展 ToList/Get/OrderBy/Where/ToPage
    [转载]宏定义
    【转载】scanf,sscanf高级用法
    C开发机顶盒实战应用代码片段
    指针精华口诀,短小精悍
    C# linq泛型 字典集合 排序
    c开发机顶盒实战应用代码片段2
  • 原文地址:https://www.cnblogs.com/zdjBlog/p/13275148.html
Copyright © 2011-2022 走看看