正则表达式还在搜?看完自己写


theme: channing-cyan

古人学问无遗力,少壮工夫老始成。
纸上得来终觉浅,绝知此事要躬行。

前言

最近又双叒叕实现了一批正则,过程很简单,ctrl+c复制正则需求,打开搜索引擎,ctrl+v粘贴,打开链接,再ctrl+c复制正则表达式,ctrl+v粘贴,搞定。作为一名CV工程师,面向搜索引擎编程,这很合理。接下来就是轻松愉快的摸鱼时间,打开掘金,翻来覆去,横竖静不下心,进入不了摸鱼状态,仔细看了半天,才从字缝里看出字来,满篇都写着两个字是学习。好吧,既然静不下心来摸鱼,索性研究下正则表达式吧,自己实现下,总是复制粘贴也是有些乏味。

正则表达式

正则表达式(Regular Expression)描述了字符串的构成模式,常被用于校验字符串是否符合预定的格式要求。

规则:按位描述,一位一位的匹配字符串的构成规则;

创建方式

创建方式有两种,创建出的正则表达式它的类型是对象:

  • /内容/
//匹配一个以k开头的字符
let reg = /^k/;
let str = 'kunkun'
let str1 = 'ikun'
console.log(reg.test(str));     // true
console.log(reg.test(str));     // false

  • new RegExp(‘内容’) ,使用这种方式创建正则表达式要注意转义字符;
let reg = new RegExp('^k');
let str = 'kunkun'
let str1 = 'ikun'
console.log(reg.test(str));     // true
console.log(reg.test(str));     // false

元字符

正则表达式由两种字符组成,原义文本字符和元字符。文本字符不用过多解释,是啥就是啥,元字符表示在正则表达式中具有特殊含义的字符,下面我们来看一下常用的元字符。

元字符 作用
^ 匹配开头
$ 匹配结尾
\d 匹配一个数字
\D 匹配一个非数字
\w 匹配一个单字字符(数字、字母、下划线)
\W 匹配一个非单字字符
\s 匹配一个不可见字符(空格、换行、制表符)
\S 匹配任何可见字符
. 匹配任何单个字符(除了“\n”和”\r”,要匹配得使用中括号)
\b 匹配一个字符边界
\B 匹配非字符边界
() 括号之间的表达式被定义为组,匹配到的字符保存到一个临时区域(一个正则表达式中最多保存9个)
| 逻辑或
//匹配以a开头的字符
let reg = /^a/;
let str = 'ab';
console.log(reg.test(str));     // true

//匹配以a结尾的字符
let reg = /a$/;
let str = 'cba';
console.log(reg.test(str));     // true

//匹配数字
let reg = /\d/;
let str = '123';
console.log(reg.test(str));     // true

//匹配非数字
let reg = /\D/;
let str = 'abc';
console.log(reg.test(str));     // true

//匹配一个单字字符(数字、字母、下划线)
let reg = /\w/;
let str = '1';
let str1 = 'a';
let str2 = '_';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true

//匹配一个非单字字符
let reg = /\W/;
let str = '*';
console.log(reg.test(str));     // true

//匹配一个不可见字符(空格、换行、制表符)
let reg = /\s/;
let str = ' ';
let str1 = ' ';
let str2 = '\n';
let str3 = 'a';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true
console.log(reg.test(str3));     // false

//匹配任何可见字符
let reg = /\S/;
let str = ' ';
let str1 = ' ';
let str2 = '\n';
let str3 = 'a';
console.log(reg.test(str));     // false
console.log(reg.test(str1));     // false
console.log(reg.test(str2));     // false
console.log(reg.test(str3));     // true

//匹配任何单个字符
let reg = /./;
let str = 'a';
let str1 = '\n';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

//匹配前面的子表达式任意次,子表达式匹配到即可
let reg = /ab*/;
let str = 'a';
let str1 = 'ab';
let str2 = 'abb';
let str3 = 'ccab';
let str4 = 'ccc';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true
console.log(reg.test(str3));     // true
console.log(reg.test(str4));     // false

//匹配前面的子表达式一次或多次,必须匹配到
let reg = /ab+/;
let str = 'abbbb';
let str1 = 'a';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

//匹配前面的子表达式零次或一次,匹配不匹配都可以,通常用于其他条件的补充
let reg = /a?/;
let str = 'abbbb'
let str1 = 'a';
let str2 = 'b';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true

//匹配一个边界字符
let reg = /ab\b/;
let str = 'ab';
let str1 = 'abc';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

//匹配非边界字符
let reg = /ab\B/;
let str = 'ab';
let str1 = 'abc';
console.log(reg.test(str));     // false
console.log(reg.test(str1));     // true

//匹配a或b
let reg = /a|b/i;
let str = 'a';
let str1 = 'b';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true

//匹配ab,为一组,不加括号则是仅匹配b
let reg = /(ab){1}/;
let str = 'ab';
let str1 = 'b';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

注意:因为元字符的存在,正则表达式中某些字符具有特殊含义,当我们使用正则表达式匹配一个符号时,可以再前面加上一个反斜杠(\),不管他是否具有特殊含义。

方括号

正则表达式在方括号内可以创建一个任意位的字符合集,表示匹配方括号内的任意一个字符,通常是和某些元字符等价的;

方括号表示法 等价的元字符
[0-9] \d
[^0-9] \D
[a-zA-Z0-9_] \w
[^a-zA-Z0-9_] \W
[ \f\n\r\t\v] \s
[^ \f\n\r\t\v] \S
[^\r\n] .
//匹配数字
let reg = /[0-9]/;
let str = '123';
console.log(reg.test(str));     // true

//匹配非数字
let reg = /[^0-9]/;
let str = 'abc';
console.log(reg.test(str));     // true

//匹配一个单字字符(数字、字母、下划线)
let reg = /[a-zA-Z0-9_]/;
let str = '1';
let str1 = 'a';
let str2 = '_';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true

//匹配一个非单字字符
let reg = /[^a-zA-Z0-9_]/;
let str = '*';
console.log(reg.test(str));     // true

匹配一个不可见字符(空格、换行、制表符)
let reg = /[ \f\n\r\t\v]/;
let str = ' ';
let str1 = '    ';
let str2 = '\n';
let str3 = 'a';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // true
console.log(reg.test(str3));     // false

//匹配任何可见字符
let reg = /[^ \f\n\r\t\v]/;
let str = ' ';
let str1 = ' ';
let str2 = '\n';
let str3 = 'a';
console.log(reg.test(str));     // false
console.log(reg.test(str1));     // false
console.log(reg.test(str2));     // false
console.log(reg.test(str3));     // true

//匹配任何单个字符
let reg = /[^\r\n]/;
let str = 'a';
let str1 = '\n';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

量词

量词 作用
* 匹配前面的子表达式任意次
+ 匹配前面的子表达式一次或多次,尽可能多的,贪婪的
? 匹配前面的子表达式零次或一次
{n} n是一个非负整数,匹配前面一个字符出现了n次
{n,} n是一个非负整数,匹配前面一个字符至少出现了n次
{n,m} n和m都是非负整数,n<=m,匹配前面的字符至少出现了n次,最多m次
//匹配a出现了两次
let reg = /a{2}/;
let str = 'aa';
let str1 = 'a';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // false

//匹配a至少出现了2次
let reg = /a{2}/;
let str = 'aa';
let str1 = 'aaa';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true

//匹配b至少出现了1次,最多出现3次
let reg = /ab{1,3}/;
let str = 'ab';
let str1 = 'abbb';
let str2 = 'abbbbbbb';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
console.log(reg.test(str2));     // false

修饰符

修饰符也叫标志符,通过正则表达式实现检索,通常写在正则表达式的结尾与字符串的方法结合使用。

修饰符 作用
i 不区分大小写搜索
g 全局搜索
//匹配ab,不区分大小写
let reg = /ab/i;
let str = 'ab';
let str1 = 'AB';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true

//let reg = new RegExp('ab','i');

正则表达式的相关方法

test() 用于验证某字符串是否匹配正则表达式,返回ture或false;

exec()用于搜索查找某字符串是否包含匹配改正则表达式的内容,返回一个匹配结果数组,这个匹配仅仅会匹配到字符串符合正则的一部分;

let str = 'abc123def456ghi789';
let regexp = /\d+/g;    
let result1 = regexp.exec(str);
let result2 = regexp.exec(str);
let result3 = regexp.exec(str);
let result4 = regexp.exec(str);
console.log(result1);  //["123", index: 3, input: "abc123def456ghi789", groups: undefined]
console.log(result2);  //["456", index: 9, input: "abc123def456ghi789", groups: undefined]
console.log(result3);  //["789", index: 15, input: "abc123def456ghi789", groups: undefined]
 console.log(result4);  //null

当加上g修饰符时(通常都会加上),使用exec会默认记录到上次匹配的节点,再次调用时直接匹配到后面的符合正则表达式的字符,直到没有符合正则表达式的字符,会返回null;

配合while语句可以将符合正则的字符逐条遍历出来:

let result;
while (result = regexp.exec(str)) {
 console.log(result);
 }
 //["123", index: 3, input: "abc123def456ghi789", groups: undefined]
 //["456", index: 9, input: "abc123def456ghi789", groups: undefined]
 //["789", index: 15, input: "abc123def456ghi789", groups: undefined]

与字符串的方法结合

search()

search()方法用于在字符串中根据正则表达式进行查找匹配,会返回首次匹配到的内容的索引,没有则返回-1;类似indexOf()方法。

let str = 'abc123aaa456bbb';
let result = str.search(/\d+/g);
let result1 = str.search(/m/g);
console.log(result);       // 3
console.log(result1);      //-1

replace()

replace() 非常非常非常常用的方法,替换匹配到的子字符串。参数可以直接写字符串,也可以写成正则表达式或函数。

//尽可能的匹配小写字母进行替换
let result = str.replace(/[a-z]+/g, 'kunkun');  
console.log(result);       //kunkun123kunkun456kunkun

split()

split()通常用来把字符串分割成数组,正则表达式可以对分割进行很好的扩展。

let str = 'abc123aaa456bbb';
//根据数字进行分割
let result = str.split(/\d+/g);
console.log(result);       //["abc", "aaa", "bbb"]

match()

match()根据正则表达式对字符串进行查找匹配,返回一个包含匹配内容数组,没有则返回null。

let str = 'abc123aaa456bbb';
let result = str.match(/\d+/g);
console.log(result);       // ["123", "456"]

常用的正则表达式

//匹配座机号码
let reg = /\d{3}-\d{8}|\d{4}-\d{7}/;
let str = '029-88888888';
let str1 = '0544-4405222';
console.log(reg.test(str));     // true
console.log(reg.test(str1));     // true
 
//匹配手机号码
let reg = /^[1][3,4,5,6.7,8,9][0-9]{9}$/;
let str = '13333333333';
console.log(reg.test(str));     // true

//匹配邮箱地址
let reg = /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
let str = '111111@qq.com';
console.log(reg.test(str));     // true

//匹配邮政编码
let reg = /[1-9]\d{5}(?!\d)/;
let str = '963321';
console.log(reg.test(str));     // true

//匹配URL
let reg = /[a-zA-z]+:\/\/[^\s]*/;
let str = 'https://www.baidu.com/?tn=65081411_1_oem_dg';
console.log(reg.test(str));     // true

//匹配ip
let reg = /\d+\.\d+\.\d+\.\d+/;
let str = '127.0.0.1';
console.log(reg.test(str));     // true

//匹配汉字,需要写清楚中文字符集
let reg = /^[\u4e00-\u9fa5]{0,}$/;
let str = '坤坤';
console.log(reg.test(str));     // true

写在最后

常用的正则表达式规则基本是这些了,熟悉后可以实现大部分的正则表达式,很多正则看似比较繁琐,实现起来不过是些简单规则的组合,只是我们脑海中没有相应的知识储备。

很多知识点也是这样,我们可能感觉自己有些印象,曾经也学过,但当深究的时候就是一知半解。一些常见的业务场景,网上解决方案很多,我们在开发的过程中很容易习惯性的依赖搜索引擎,这样也许效率比较高,但很容易给自己一种”我会“的假象,”我会根据搜索引擎使用“远不等于“我会”。

我是侃如,如果这篇文章对你有帮助,不妨点个赞吧。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
相关推荐
  • 暂无相关文章
  • 评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容