正则表达式总结

正则表达式( regular expression )

  • RegExp
  • 用处: 匹配, 验证; 替换, 截取, 分析

元字符

#### 基本元字符:

       匹配任意的非换行字符, 常常表示通用元字符使用 [\s\S]
       匹配一个出现在 [] 中的字符, [123456789123456789123456789], [a-z0-9A-Z]
       计算机只认识 数字, 所以我们写的字符串计算机其实不是以字符串的形式存储
                        有一个编码系统: unicode
                             '0'                 48
                             '1'                 49
                             ...
                             '9'                 57
                         写上:  '012' , 在内存中存储: 48 49 50 
                         需要记住的是:
                             '0'                 48
                             'a'                 97
                             'A'                 65
                             \u0030
         ()              1> 分组; 2> 提升优先级
         |               或者
                         匹配 foot 或者 food
                         foot|food
                         注意: | 具有最低优先级
                         ^(foot|food)$
   - 常见的用法
                         例如要匹配jq的属性选择器: 
                         [name]
                         [name=value]
                         用正则: \[\w+=\w+\]|\[\w+\]
                         jq 的写法: \[\w+(=\w+|)\] 
                         (foot|food)     匹配: 'foot' 或者 'food'
                         (foot|)         匹配: 'foot' 或者 ''
                         food(=food|)    匹配: 'food=food' 或者 'food'
                         \w+(=\w+|)      匹配: '字符=字符' 或 '字符'
                         \[\w+(=\w+|)\]  匹配: '[xxx]' 或 '[xxx=vvv]'
                         \[\s*(\w+)\s*(?:([|!^$~]?=)\s*(\w+)|)\s*\]
                         =>
                        \[   \s*     (\w+)  \s*   (?:   ([|!^$~]?=)     \s*    (\w+)   |)   \s*   \]

#### 限定元字符

        +                   (abc)+              {1,}
        *                                       {0,}
        ?
        {n}
        {n,}
        {n,m}
#### 首尾元字符
        ^                   必须以 xxx 开头
                            表示否定:
                                [abc]           用来匹配 一个 字符 a, 或 b, 或 c
                                [^abc]          用来匹配一个字符, 要求不允许是 a, b, c
        $                   必须以 xxx 结尾
                            表示组引用
                                a(b)c
#### 简写元字符
        \w                  word
        \W
        \s                  space
        \S
        \d                  digit
        \D
#### 其他:
        (?: )
        \1

基本的匹配案例

    如何匹配
    1) 匹配任意的自然数, 就是 0, 1, 2, 3, ...
        [0-9]  等价于 \d
        分类讨论
            -> 一位数字: \d
            -> 两位: [1-9]\d
            -> 任意位( 除了一位 ): [1-9]\d+
        合并: 
            \d|[1-9]\d+
        可以进行演变( 用不同的方法写同一个例子 )
            [1-9]\d*|0
            [1-9][0-9]*|0
            ...
    2) 匹配任意的整数, 0, +1, -1, +2, -2, ...
        [+-]?[1-9][0-9]*|0
        (+|-|)[1-9][0-9]*|0
        ...

    3) 匹配任意的实数, 0.01, 0.0000123, -0.1234567
        整数 + 小数部分
        分类( 划归 )
            ((+|-|)[1-9][0-9]*|0)(\.\d+|)

        无法匹配 -0.1
        无非就是不允许匹配 -0.0+

        使用正则的原则: 够用即可, 尽可能写成多步的判断, 要保证正则表达式的尽可能简洁
        -0+(\.|)0*
        if ( !... ) {
            if ( ... )
        }
        \d{17}|[\dxX]
        \d{11}

    4) 匹配邮箱
        [^@]+@[^@]+
        如果想要严谨一点
        邮箱分成用户名 和 域名
        用户名: 可以有数字, 字母下划线组成( 还有一些特殊字符 )
            [\w\-]+
        域名: xxx.com.cn.xxxx
            [\w\-]+(\.[\w\-]+)+

    5) 匹配 ip 地址
        采用数字点分的方法描述, 而且每一个数字的取值在 0-255 之间, 都可以取到
        0.0.0.0
        255.255.255.255
        123.124.125.126
        ...
        \d{1,3}(\.\d{1,3}){3} 或者: \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} 

        利用正则实现匹配 0 到 255 的数字
        分类:
        一位: [0-9]
        两位: 10-99
              [1-9][0-9]
        三位: 100-255
              开始为 1 的: 100-199: 1[0-9][0-9]
              开始为 2 的: 200-255: 
                中间为 0-4 的: 2[0-4][0-9]
                中间为 5 的: 25[0-5]

        [0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]

        IP:
        [0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]\.[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]

 - 如配匹配计算机中的一个文件路径全名
        例如: C:\myMusics\list\myFavorite\rain.MP3
            盘符: 一个字符: a-z, 简单的写 . 如果想要严格处理 [a-z]
            冒号和斜线: :\\
            路径(文件夹的名字): .+\\ 如果想要精确: ([^|:\?\*><\\\/\"]+\\)* 
            文件名: .+\..+ 如果想要精确一点: [^|:\?\*><\\\/\"]+\.[^|:\?\*><\\\/\"]+

            组合起来:
                .:.*\\.+\..+
            注意: 正则表达式有贪婪模式
                 C:\myMusics\list\myFavorite\rain.MP3
                .:(.*)\\.+\..+
                .:.*\\.+.+
            如果一个正则表达式中有多个 .+ 或 .* 的结构, 如果造成了匹配的歧义, 满足一个规则. 即贪婪模式
            从左往右 匹配个数的能力是左强又弱, 而且只有两个级别, 要么强, 要么弱

                例如: 
                    var s = '1234567890';
                    //        1 2 3
                    var r = /(.+)(.+)(.+)/;

                    var res = r.exec( s );
            例如匹配 div 标签
                    var r = /<div.*?>.*<\/div>/;
            如果不希望有贪婪模式在 限定元字符( +, * 等 )后写上 ?

字符串提取( 解析 )

    .exec 方法
    利用正则表达式, 去处理字符串, 并将字符串中符合正则表达式的数据取出来 
    var s = '1234567';
    var r = /\d/;
    var m = r.exec( s );   // m 是 match 的简写, 表示捕获
    // 如果匹配上了, 就返回数组, 第 0 项 就是匹配到的结果, 如果正则表达式中有 分组
    // 分组都是从 1 开始的编号, 那么对应的 第 n 组匹配到的结果就在这个数组的第 n 项
    // 注意: 是真数组
    // 如果没有匹配到 则返回 null

    分组: 就是 ()
    从左往右数 (, 第一个开始编号, 从 1 开始编号, 此时编号完成以后, 对应圆括号组成的就是对应的组
    //         1   2  34       5
    例如: r = /(\d)(\d((\d)\d))(\d)/;

    例子:获取网页中的QQ号: 
    想要做一个推广, 在论坛中发布我有XXX的视频, 如果想要的留下邮箱
    如果有人留下的是 QQ 号, 将其拉到一个群里

    注意: exec 匹配提取, 只能匹配提取第一个被捕获的数据
    如果需要匹配字符串中所有符合要求的字符串
    1) 开启全局模式, 在正则后面写上一个 g, 或在构造函数的 第二个参数中提供 'g'
        创建正则:
            -> 字面量:   /.+\\.+/g
            -> 构造函数: new RegExp( '.+\\\\.+', 'g' )
    2) 开启全局模式后, 使用 正则表达式对象 调用 exec 方法一次, 就会从 0 位置或上一次结束的位置开始
        查找下一个匹配结果, 如果查找到结果则返回对应数组, 如果没有查找到( 即, 找完了 )就会返回 null.
        如果还继续调用 exec, 那么就从头开始再查一次.
    例如:
        var s = '123';
        var r = /\d/g;

        r.exec( s );   // [ '1' ]
        r.exec( s );   // [ '2' ]
        r.exec( s );   // [ '3' ]
        r.exec( s );   // null
        r.exec( s );   // [ '1' ]
        ...

        一般要取到所有的数据, 可以使用下面的代码结构
        var m;
        while ( ( m = r.exec( s ) ) != null ) {
            // 此时 m 就是找到的结果
        }

字符串替换

    .replace( 正则表达式, 需要替换的字符串 )
    1) 将一个字符串中所有的 - 换成一个连线
        var s = 'a-----------------------------------b----------------------c----d';
        // => a-b-c-d
        var res = s.replace( /-+/g, '-' );
        应用背景

            /\*.*?([\r\n]+.*?)*\*/

        换行: \r\n
        因此 \r 是回车的意思
             \n 是换行的意思
        平时在处理换行的时候要注意: 在 有些时候是 \r\n, 有些时候是 \n
        在 类 Unix 操作系统中( unix, linux, mac ) 换行都是 \n
        在 windows 中是 换行是 \r\n
    2) 在替换中还可以使用组
        var s = '2012-3-4';
        // 在不同的系统中想要显示成
        // 2012年3月4日
        // 3月4日2012年
        // 4/3/2012
        // ...
        var r = /(\d+)\-(\d+)\-(\d+)/;

        var res = s.replace( r, '$1年$2月$3日' )
    3) 替换的时候, 第二参数可以是函数, 函数的参数为, 匹配到的数组的散列值
        利用函数的返回值替换匹配到的结果

        var s = '2012-3-4';
        var r = /(\d+)\-(\d+)\-(\d+)/;

        s.replace( r, function ( match, g1, g2, g3 ) { 
            return g1 + '年' + g2 + '月' + g3 + '日';
        });

        电话号码的加密
        var list = [
            '12345678901',
            '12345678912',
            '12345678923',
            '12345678934',
            '12345678945',
            '12345678956'
        ];

        var res = list.map( function ( v ) {
            //                 电话号码的前4位
            //                              电话号码的后 2 位
            return v.replace( /(\d{4})(\d+)(\d{2})/, function ( a, b, c, d ) {
                // a 就是匹配到的 电话号码
                // b 就是匹配到的 电话号码的前 4 位
                // c 就是匹配到的电话号码的 中间 5 位
                // d 就是匹配到的电话号码的 后 2 位
                return b + '***********'.slice( 0, c.length ) + d;
                // return b + '*****' + d;
            });
        });

    (?:)
    var s = '1234567';
    //        1   2       3     4
    var r1 = /(\d)(\d\d\d)(\d\d)(\d)/;
    r1.exec( s ); // => [ '1234567', '1', '234', '56', '7' ]
    \
    //        1             2     3
    var r2 = /(\d)(?:\d\d\d)(\d\d)(\d)/;
    r2.exec( s ); // => [ '1234567', '1', '56', '7' ]> 这里输入引用文本

希望对大家有帮助O(∩_∩)O~~

转载于:https://my.oschina.net/u/3317396/blog/899198

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值