正则表达式
一个用来描述或者匹配一系列符合某个语法规则的字符串的语言。
let str = 'sadad5656dada655ad223';
// let nums = [...str].filter(a =>!Number.isNaN(parseInt(a)));
let nums = str.match(/\d/g)
console.log(nums.join(''))
应用场合
数据验证、文本替换、内容检索、过滤内容
创建正则表达式
1、通过构造函数创建
- var reg = new RegExp("正则表达式","修饰符");
2、通过字面量方式创建
- var reg = /正则表达式/修饰符,"/ /" 称为定界符
3、区别
- 字面量创建方式不能进行字符串拼接,实例创建方式可以,方便使用变量
- 字面量创建方式特殊含义的字符不需要转义,实例创建方式需要转义
var reg = new RegExp("abc",'g');
var result = reg.test("abcde");
console.log(result); // true
var reg = /abc/g;
var result = reg.test("abcde");
console.log(result); // true
var str = 'abc';
var reg1 = new RegExp(str + '123');
var reg2 = /abc/ ;
console.log(reg1); // /abc123/
console.log(reg2); // /abc/
var reg1 = new RegExp('\d');
console.log(reg1); // /d/
var reg2 = new RegExp('\\d')
console.log(reg2); // /\d/
var reg3 = /\d/;
console.log(reg3); // /\d/
修饰符
- i 表示不区分大小写(如果表达式里面有 a, 那么 A 也是匹配对象)
- m 多行匹配,即在到达一行文本末尾时还会继续寻常下一行中是否与正则匹配的项
- g 全局匹配 模式应用于所有字符串,而非在找到第一个匹配项时停止
- u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字)
let str = 'ada1212中文dada'
let result = str.match(/\p{sc=Han}/gu);
console.log(result)
元字符
代表特殊含义的元字符
- \d 匹配任意一个数字 [0-9]
- \D 与除了数字以外的任何一个字符匹配 [^0-9]
- \w 与任意一个英文字母,数字或下划线匹配 [a-z0-9A-Z_]
- \W 除了字母,数字或下划线外与任何一个字符匹配 [^a-z0-9A-Z_]
- \s 与任意一个空白字符匹配
- \S 与除了空白符外任意一个字符匹配
- \f 换页符
- \n 换行符
- \r 回车符
- \t 制表符
- \v 垂直制表符
let str="aaaBBB_$ @ $_123ccc";
let result=str.replace(/\d/g, '*');
console.log(result); // aaaBBB_$ @ $_***ccc
let result=str.replace(/\D/g, '*');
console.log(result); // *************123***
let result=str.replace(/\w/g, '*');
console.log(result); // *******$ @ $*******
var result=str.replace(/\W/g, '*');
console.log(result); // aaaBBB_*****_123ccc
let result=str.replace(/\s/g, '*');
console.log(result); // aaaBBB_$*@*$_123ccc
let result=str.replace(/\S/g, '*');
console.log(result); // ******** * ********
- \ 转义字符
- | 或者
- () 原子组
- [] 原子表
- 点(.) 除了\n之外的任意一个字符,如果特指点,要加转义符 .
- \b 匹配边界 字符串的开头和结尾 空格的两边都是边界 => 不占用字符串位数
- ^ 字符边界约束,限定开始位置 => 本身不占位置
- $ 字符边界约束,限定结束位置 => 本身不占位置
- [a-z] 任意字母 []中的表示任意一个都可以(原子表)
- [^a-z] 非字母 []中^代表除了
// /1取第一个原子组
let str = '2020-05-01';
let result = str.match(/^\d{4}(-)\d{2}\1\d{2}$/g);
console.log(result);
let num = '17605888888';
let result = /^1\d{10}$/.test(num);
console.log(result) // true
let str = '我是中文007-888888';
let result = str.match(/[^\d\-]+/gi);
// let result = str.match(/\p{sc=Han}+/gu); // 匹配中文
console.log(result) // ["我是中文"]
let str =' 我是空格君 ';
let reg = /^\s+|\s+$/g; //匹配开头结尾空格
let res = str.replace(reg,'');
console.log('('+res+')') //(我是空格君)
let mail = 'lichi123@sina.com.cn';
let result = mail.match(/^[\w-]+@([\w-]+\.)+(com|cn|org|net)$/i);
console.log(result)
// 特殊
// 1、一般[]中的字符没有特殊含义
let str1 = 'abc';
let str2 = 'dbc';
let str3 = '.bc';
let reg = /[ab.]bc/; //此时的 . 就表示普通的字符串点,[()] ()也是普通的括号
console.log(reg.test(str1)) //true
console.log(reg.test(str2)) //false
console.log(reg.test(str3)) //true
// 2、[]中,不会出现两位数
// 例如:匹配从18到65年龄段所有的人
let num = 10;
let reg = /(18|19)|([2-5]\d)|(6[0-5])/;
let result=reg.test(num);
console.log(result);
// 3、[/s/S] [/d/D] 匹配所有内容
//4、批量使用正则
let password = 'ab125A';
let regs = [
/^[a-z0-9]{5,10}$/i,
/[A-Z]/,
/[0-9]/
]
let result = regs.every(e=>e.test(password));
console.log(result)
代表次数的量词元字符
- n* 匹配任何包含零个或多个 n 的字符串
- n+ 匹配任何包含至少一个 n 的字符串
- n? 匹配任何包含零个或一个 n 的字符串
- {n} 重复n次
- {n,} 重复n次或更多次
- {n,m} 重复n到m次
let str = 'abccccccc';
let result = str.match(/abd*/); // str.match(/abc*/);
console.log(result)
let str = 'ababcccccccab';
let result = str.match(/(ab)+/g);
console.log(result)
let str = `
https://www.baidu.com
http://www.baidu.com
http://baidu.com
`;
let result = str.match(/https?:\/\/(((www)\.)?\w+\.(com|cn|org))/gi);
console.log(result)
let str = '1223334444';
let reg = /\d{2}/g;
let res = str.match(reg);
console.log(res) //["12", "23", "33", "44", "44"]
断言匹配
// 先行断言 (?=条件)
let str="17605889923"
let reg=/\d{7}(?=\d{4})/g; // 取末尾4位之前的字符串
let result = reg.exec(str);
console.log(result);
// 后发断言 (?<=条件)
let reg=/(?<=\d{7})\d{4}/g; // 取开头7位之后的字符串
let result = str.replace(reg,v=>{
// console.log(v)
return '*'.repeat('4')
})
console.log(result); // 1760588****
// 负向零宽先行断言 (?!条件)
let str="aaaa5555bbbb"
let reg=/[a-z]+(?!\d+)$/; // 取末尾不是数字的字符串
let result = reg.exec(str);
console.log(result);
// 负向零宽后发断言 (?<!条件)
let str="aaaa5555bbbb"
let reg=/(?<!\d+)[a-z]+/; // 取开头不是数字的字符串
let result = reg.exec(str);
console.log(result);
正则的特性
- 贪婪性
正则在捕获时,每一次会尽可能多的去捕获符合条件的内容。如果我们想尽可能的少的去捕获符合条件的字符串的话,可以在量词元字符后加? - 懒惰性
正则在成功捕获一次后不管后边的字符串有没有符合条件的都不再捕获。如果想捕获目标中所有符合条件的字符串的话,我们可以用标识符g来标明是全局捕获
var str = '123aaa456';
var reg = /\d+/; //只捕获一次,一次尽可能多的捕获
var res = str.match(reg)
console.log(res)
// ["123", index: 0, input: "123aaa456"]
reg = /\d+?/g; //解决贪婪性、懒惰性
res = str.match(reg)
console.log(res)
// ["1", "2", "3", "4", "5", "6"]
正则方法
- reg.test(str) 用来验证字符串是否符合正则 符合返回true 否则返回false
let str = 'abc';
let reg = /\w+/;
console.log(reg.test(str)); //true
- reg.exec(str) 用来捕获符合规则的字符串,成功返回数组,失败返回null
// let reg=/\w/;
// let reg=/(?<str>\w)/g; // ?<str>原子组别名 => groups
let reg=/\w/g;
let str="abcdefg"
console.log(reg.lastIndex);
let result = reg.exec(str);
console.log(result); // ["a", index: 0, input: "abcdefg", groups: undefined]
console.log(reg.lastIndex);
let result = reg.exec(str)
console.log(result); // ["b", index: 1, input: "abcdefg", groups: undefined]
while (result = reg.exec(str)) {
console.log(result)
}
字符串方法
- str.match(reg) 用来捕获符合规则的字符串,成功返回数组,失败返回null,和 reg.exec(str)类似,进行全局匹配时二者有所不同,match方法会一次性把符合匹配条件的字符串全部捕获到数组中,
如果想用exec来达到同样的效果需要执行多次exec方法。
// var reg=/\w/;
var reg=/\w/g;
var str="abcdefg"
var result=str.match(reg);
console.log(result); // ["a", "b", "c", "d", "e", "f", "g"]
// match和exec都可以受到分组()的影响,不过match只在没有标识符g的情况下才显示小分组的内容,如果有全局g,则match会一次性全部捕获放到数组中
var str = 'abc';
var reg = /(a)(b)(c)/;
console.log( str.match(reg) );
// ["abc", "a", "b", "c", index: 0, input: "abc"]
console.log( reg.exec(str) );
// ["abc", "a", "b", "c", index: 0, input: "abc"]
//当有全局g的情况下
// ?: 返回值忽略内容
var str = 'abc';
var reg = /(a)(?:b)(c)/g;
// console.log( str.match(reg) );
// ["abc"]
console.log( reg.exec(str) );
// ["abc", "a", "b", "c", index: 0, input: "abc"]
- str.search(reg) 反回索引位置,不支持全局索引(即g修饰符无效)找到即停止搜索
var str = "www.baidu.com";
console.log(str.search(/baidu/));
- str.replace(reg) 替换
// $1 $2 原子组中匹配到的值,从左到右
// ?<name> 原子组别名
let str = '(010)88888 (020)99999';
let res = str.replace(/\((?<num>\d{3})\)(\d{5})/g,'$<num>-$2')
console.log(res)
// $& 匹配到的值
// $` 匹配到的值前面的所有内容
let str = 'aaa567aaa';
let res = str.replace(/\d/g,'$&U')
console.log(res)
// 要求 http => https 加 www.
// ...args 剩余参数
let str = 'http://baidu.com';
let result = str.replace(/(http)(:\/\/)(www.)?\w/g,(v,...args)=>{
console.log(args)
args[0]+='s';
args[2]= args[2]||'www.';
return args.splice(0,3).join('');
})
console.log(result)
- str.split(reg) 拆分字符串,参数可以为字符串或正则表达式
let str = "2020-05-01";
console.log(str.split(/-|\//g)); // ["2020", "05", "01"]
网友评论