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
写在最后
常用的正则表达式规则基本是这些了,熟悉后可以实现大部分的正则表达式,很多正则看似比较繁琐,实现起来不过是些简单规则的组合,只是我们脑海中没有相应的知识储备。
很多知识点也是这样,我们可能感觉自己有些印象,曾经也学过,但当深究的时候就是一知半解。一些常见的业务场景,网上解决方案很多,我们在开发的过程中很容易习惯性的依赖搜索引擎,这样也许效率比较高,但很容易给自己一种”我会“的假象,”我会根据搜索引擎使用“远不等于“我会”。
我是侃如,如果这篇文章对你有帮助,不妨点个赞吧。
暂无评论内容