正则表达式 - Javascript

144 阅读3分钟

正则表达式

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。不同语言的正则基本都大同小异。

使用正则的目的

对给定的字符串进行处理 匹配 捕获,

匹配:匹配的意思就是检查一个字符串是否符合正则的规则。

捕获:捕获的意思就是获取到字符串中符合这个正则规则的部分。

正则表达式的特点

1.灵活性、逻辑性、实用性都特别的好

2.可以迅速地用极简单的方式达到字符串的复杂控制

3.对新手来说不太友好,有点晦涩难懂

定义正则的方式

let reg = /111/;  //字面量方式    /元字符/  在正则//中间包裹的称为元字符

let reg1 = new Regexp(1111); //构造函数方式

正则元字符介绍

\ 将字符进行转义,使其不再具备特殊含义
\1 代表反向引用 引用分组第一次捕获的内容
\2 代表反向引用 引用分组第二次捕获的内容
^ 表示以什么开头
$ 表示以什么结束
\d 在正则中代表数字的意思 也代表[0-9]
\D  代表除了数字以外的其他字符
\w 代表数字、字母、下划线,包含大小写
\W 代表除字母、字母、下划线外的其他字符
? 代表前面的字符出现01次
* 代表前面的字符出现0到多次
+ 代表前面的字符出现1到多次
{n} 代表前面的字符出现n次 例{3}出现三次
{n,} 代表前面的字符出现n到多次
{n,m} 代表前面的字符出现n到m次
[ab] 代表a或者b /^[xy]$/ 要么以x开头,要么以y结尾
[^ab] 取非,表示除ab以外的其他字符
[a-z] 代表小写字母 字符串中包含a-z中的任意一个字符
[A-Z] 代表大写字母 字符串中包含A-Z中的任意一个字符 
也可以这么写[a-zA-Z] 字符串中包含一个大写字母或者一个小写字母
[]内只能代表一个字符
[0-9] 代表数字 等同于\d
a|b 代表a或者b []只能代表一位 而 | 可以代表多位 例:/^13|12$/ 以13开头或者以12结尾的字符串
. 代表除换行以外的所有字符   在[]里面.点只代表点本身,没有特殊含义
() 分组,提升优先级(捕获的概念) 例:/^(8|6)$/ 开头和结尾是8或者6
[?=] 正向预查  正向预查不占位
[?<=] 与正向预查功能相同,只是方向相反

正则修饰符
g global  全局匹配  最多用于捕获
i ignoreCase 忽略大小写
m multiline 多行匹配  每一行都是新的开始

正则中的匹配

匹配的意思就是检查字符串是否符合正则的规则,符合则返回true,不符合则返回false,匹配大多用于用户输入信息检测格式是否合法,接下来我们来看案例。

匹配的方法

test:正则自带的用于正则匹配的方法

正则匹配手机号

     let cellPhone = '17325164450'; //定义一个字符串
     let reg = /^1[3578]\d{9}$/; //定义一个正则
     let res = reg.test(cellPhone);
     console.log(res); //结果为true

正则匹配邮箱

let E_mail = "15454545440@163.com";
let reg = /^\d{5,11}\@163|qq\.com$/;//简易版匹配qq和163邮箱
let res = reg.test(E_mail);//结果为true

匹配身份证号

    let str = '140531199611282111';
    let reg = /\d{6}(19\d{2}|20[01]\d|202[0-2])(0[1-9]|1[0-2])([0-2][1-9]|10|20|3[01])\d{3}(\d|X)/;
    let res = reg.test(str);
    console.log(res);//打印 true

匹配密码:只能是数字 字母 _. - + @ $ 组成的8-15位字符

  let reg = /\d|[A-Za-z]|[\_.\-\+\@\$]{8,15}/;
    let str = 'abcd12345678910';
    let res = reg.test(str);
    console.log(res);//此处为 true

正则中的捕获

捕获的意思就是获取字符串中符合正则规则的部分,可应用与URL的解析,字符串的局部替换等,以下为案例。

捕获的方法

exec:正则自带方法 用于捕获 捕获具有贪婪性 一次获取尽可能多的内容 想解决这个贪 就在量词后边加一个?,捕获的懒惰性。只获取一次 解决懒惰性 使用修饰符 g 需要手动多次捕获。

    let number = '你好888正则666';
    let reg = new RegExp(/\d+/g); //reg.lastindex代表的就是当次匹配或者捕获 对应字符串的开始索引
    console.log(reg.exec(str)); //888
    console.log(reg.exec(str)); //666
    console.log(reg.exec(str)); //null 当捕获完的时候,下一次捕获结果就会变为null
    console.log(reg.exec(str)); //888 再下一次就会从头开始捕获

match:在正则没有g修饰符的时候 match捕获的结果和exec的捕获结果是一样的一旦有g的时候 match可以目标字符串中所有匹配大正则的部分都捕捉到,但是不能捕获小分组。

replace:和match都是属于字符窗串的方法,replace用于字符串的局部替换,配合正则来使用特别的好用。

千分符案例:给字符串每隔三位加一个逗号,表示一个千位。

    let num = '123456789';
    let reg = /\d(?=(\d{3})+$)/g;
   let min =  num.spli('.')[1]; //以小数点分割字符串 防止出现小数
   let max =  num.spli('.')[0];
   let res = max.replace(reg,function($0,$1){
    return $0 + ',';
    }).repalce(/^,/,'') + (min ? '.' + min : '');//防止前面出现逗号 替换完把小数加上,没有则不加
    console.log(res);//结果为123,456,789

查找字符串中出现次数最多的字母

    let str = 'dasdnsjahfjakfhsdadsad'; //随便定义一个字符串
    let reg = /([a-zA-Z])\1+/g;
    let str1 = str.split('').sort().join('');
    let Maxlength = 0,
        MaxStr = '';
    let res = str1.replace(reg, function($0) {
        if ($0.length > MaxStr) {
            Maxlength = $0.length;
            MaxStr = $0
        }
    })
    console.log(Maxlength, MaxStr);//打印出  5 'aaaaa'

URL的解析

//以百度的域名为例
 let text = 'https://www.baidu.com/s?wd=%E9%A3%8E%E6%A0%BC%E5%92%8C&rsv_spt=1&rsv_iqid=0xc10aa6890000030c&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_dl=tb&rsv_sug3=5&rsv_sug1=1&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&inputT=1135&rsv_sug4=1325';
 let reg = /([^?&=]+)=([^&?=]+)/g;
    let obj = {};
    str.replace(reg, function($0, $1, $2) {
        return obj[$1] = $2;
    })
    console.log(obj); //对象中属性名为等号前面的值 属性值为等号后面的值

捕获身份证号中的出生日期

    let str = '140531199611282111';
    let reg = /^(\d{6})(\d{8})(\d{2})(\d)(\d|x)$/g;
    let res = str.replace(reg, function($0, $1, $2, $3, $4, $5) {
        console.log($2, $3, $4, $5);
        let res = $2.replace(/(\d{4})(\d{2})(\d{2})/, '出生日期是$1年$2月$3日');
        return res + ` 性别${$4 % 2 ?'男':'女'}`;
    })
    console.log(res);//打印 出生日期是1996年11月28日 性别男

大写字母转为小写字母 小写字母转为大写字母

 let str = 'ADSSADASFSAFsadsafaffd';
    let reg = /[A-Za-z]/g;
    let res = str.replace(reg, function($1) {
        if (/[a-z]/.test($1)) {
            return $1.toUpperCase();
        } else {
            return $1.toLowerCase();
        }
    })
    console.log(res);//打印出 adssadasfsafSADSAFAFFD

vue模板字符串引擎实现

  let temp = `我是{{name}},年龄{{age}},性别{{sex}}`;
    let data = {
        name: '张三',
        age: '18',
        sex: '男'
    };
    let reg = /\{\{([a-zA-Z]+)\}\}/g
    let res = temp.replace(reg, function($1, $2) {
        return data[$2]
    })
    console.log(res);//打印 我是张三,年龄18,性别男

总结

许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式这个概念最初是由Unix中的工具软件(例如sedgrep)普及开的。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。

正则学起来其实并没有那么难,主要的是要记住每个元字符代表的含义,把其灵活的组合到一起。并实现自己的目的,新手之所以觉得正则难的原因就是元字符比较多,比较难记。