初识正则表达式

举报
小妖现世 发表于 2020/08/09 12:07:42 2020/08/09
【摘要】 华为前端全栈第二阶段马上就结束了,希望第三阶段框架部分可以讲的深入一些,结合一些实战项目和综合应用场景,可以让我们这些小白迅速上手。最近发现前端部分还是一块内容正则表达式也是很重要,今天分享出来初识正则表达式:(regular expression)RegExp用来处理字符串的规则只能处理字符串的规则它是一个规则:可以验证字符串是否符合某个规则(test),也可以把字符中符合规则的内容捕获到...

华为前端全栈第二阶段马上就结束了,希望第三阶段框架部分可以讲的深入一些,结合一些实战项目和综合应用场景,可以让我们这些小白迅速上手。

最近发现前端部分还是一块内容正则表达式也是很重要,今天分享出来


初识正则表达式:(regular expression)RegExp

用来处理字符串的规则

只能处理字符串的规则

它是一个规则:可以验证字符串是否符合某个规则(test),也可以把字符中符合规则的内容捕获到(exec/match...)

let str="good good study,day day up!";

let reg=/\d+/;//是否包含数字

reg.test(str);//false

str='2019-08';

reg.exec(str);

编写正则表达式:

字面量创建方式:(两个斜杠之间包起来的,都是用来描述规则的元字符)

let reg=/\d+/;

构造函数模式创建:两个参数:元字符串,修饰符字符串

let reg=new RegExp(“\\d+”);

正则表达式由两部分组成:

元字符:

1、量词元字符:设置出现的次数

*:零到多次

+:一到多次

?:零次或者一次

{n}:出现n次

{n,}:出现n到多次

{n,m}:出现n到m次

2、特殊元字符:单个或者组合在一起代表特殊的含义

\:转移字符(普通-特殊-普通)

. :除\n(换行符)以外的任意字符

^:从哪一个元字符作为开始

$:以哪一个元字符作为结束

\n:换行符

\d:0~9之间的一个数字

\D:非0~9之间的一个数字(大写和小写的意思是相反的)

\w:数字、字母、下划线中的任意一个字符

\s:一个空白字符(包含空格、制表符、换页符等)

\t:一个制表符(一个tab键:四个空格)

\b:匹配一个单词的边界

x|y:x或者y中的一个字符

[xyz]:x或者y或者z中的一个字符

[^xy]:除了x/y以外的任意字符

[a-z]:指定a-z范围中的任意字符 [0-9a-zA-Z]===\w

[^a-z]:上一个取反“非”

():正则中的分组符号

(?:):只匹配不捕获

(?=):正向预查,=后面必须跟xxx

(?!):负向预查,!后面必须不跟xxx

3、普通元字符:代表本身含义

/xiaoyao/:次正则匹配的就是“xiaoyao”

([a-z])\1:让第一次分组的字符再次出现一次

修饰符:img

i:ignoreCase  忽略单词大小写匹配

m:multiline  可以进行多行匹配

g: global  全局匹配

/A/.test('lala') //false

/A/i.test('lala') //true

元字符详细解析:

^ $

let reg=/^\d/;  //数字开头为true

reg.test("xiaoyao");//false

let reg=/\d$/; //数字结尾为true

console.log(reg.test("xiaoyao2020")); //true

let reg=/\d+/; //包含数字即可

let reg=/^\d+$/; //字符串只能是和规则一致的内容

let reg=/^1\d{10}$/; //验证手机号码

转义字符:

let reg = /^2.3$/;

reg.test('2.3'); //true

reg.test('2@3'); //true

reg.test('23'); //false

let reg = /^2\.3$/;

reg.test('2.3'); //true

reg.test('2@3'); //false

let str="\\d";

reg=/^\d$/;

console.log(reg.test(str));// false

reg=/^\\d$/;

console.log(reg.test(str)); // true

x|y:

let reg = /^18|19$/; //直接x|y会存在很乱的优先级问题,一般用小括号处理:

reg.test("189")// false

let reg = /^(18|19)$/; //只能是18或19中的一个

reg.test("189")// false

reg.test("29")// false

[]:

1、中括号中出现的字符一般都代表本身的含义

let reg=/^[@+]+$/;

reg.test("@");  //true

reg.test("@@"); //false  //只能匹配一位

reg=/^[\d]$/;  //\d在中括号中还是0-9

reg.test("d");  //false

reg.test("4");  //true

2、中括号中不存在多位数

reg=[/^[18]$/; 

reg.test("1"); //true

reg.test("18");//false

正则两种创建的区别:

//构造函数因为传递的是字符串,\需要写两个才代表斜杠

let reg=/\d+/g;

reg=new RegExp("\\d+","g");

//正则表达是中的部分内容是变量存储的值

1、两个斜杠中间包起来的都是元字符(如果正则中要包含某个变量的值,则不能使用字面量方式创建)

let type="xiaoyao";

reg=/^@"+type+"@$/;

reg.test("@xiaoyao@");//false

reg.test('@"""typeee"@');//true

2、这种情况只能使用构造函数方式(因为它传递的是规则是字符串,只有这样才能进行字符串拼接)

reg=new RegExp("^@"+type+"@$");

reg.test("@xiaoyao@");//true

正则的捕获:

实现正则捕获的方法:

正则RegExp.prototype上的方法:

exec:

实现正则捕获的前提是:当前正则要和字符匹配,如果不匹配捕获的结果是null

基于exec实现正则的捕获:

1、捕获到的结果是null或者一个数组

    数字第一项:本次捕获到的内容

    其余项:对应小分组本次单独捕获的内容

    index:当前捕获内容在字符串中的起始索引

    input:原始字符串

2、每执行一次exec,只能捕获到一个符合正则规则的,但是默认情况下,获取的结果永远都是第一个匹配的,其余的捕获不到(“正则捕获的懒惰性”:解决办法:全局修饰符g)

懒惰性的原因:默认情况下lastIndex的值不会被修改,每一次都是从字符串开始位置查找,所以找到的永远只是第一个

let str="xiaoyao2019yangfan2020qihang2021";

reg.exec(str);//["2019",index:7,input:"xiaoyao2019yangfan2020qihang2021"];

reg.lastIndex:当前正则下一次匹配的起始索引位置

reg.lastIndex;//0

let reg=/\d+/g;

设置全局匹配修饰符g后,第一次匹配完,lastIndex会自己修改,全部捕获后,再次捕获的结果是null,但是lastIndex又回归了初始值零,再次捕获又从第一个开始了

let reg=/\d+/g;

if(reg.tset(str)){

    //验证:只有正则和字符串匹配我们再捕获

    console.log(reg.lastIndex);//基于test匹配验证后,lastIndex已经被修改为第一次匹配后的结果,所有下一次捕获不再从头开始了

    console.log(reg.exec(str));

}

需求:编写一个方法execAll,执行一次可以把所有匹配的结果捕获到(前提正则一定要设置全局修饰符)类似于match的源码

~function(){

    function execAll(){

        //str:要匹配的字符串

        //this:RegExp的实例

        //进来的第一件事,验证当前正则是否设置了g,不设置则不能在进行循环捕获,否则会导致死循环

        if(!this.global) {return this.exec(str)};

        //arg存储最后所有捕获的信息,res存储每一次捕获的内容[数组]

        let ary=[],

              res=this.exec(str);

        while(res){

                //把每一次捕获的内容res[0]存放到数组中

                ary.push(res[0]);

              //只要捕获的内容不为null,则继续捕获

             res=this.exec(str);  

        }

        return ary.length ===0?null:ary;

    }

    RegExp.prototype.execAll=execAll;

}();


字符串中的match方法,可以在执行一次的情况下,捕获到所有匹配的数据(前提:正则也得设置g才可以)

console.log("珠峰2019@2020培训".match(reg));

test:

let str="xiaoyao2019yangfan2020qihang2021";

let reg=/^\d+$/;

reg.test(str);//false

reg.exec(str);//null

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。