正则表达式(Regular Expression)
主要知识点
1)正则的创建
2)正则的匹配方法
3)元字符
4)字符集合
5)边界
6)分组
7)反向引用
8)数量词汇
9)匹配模式
正则在js中的使用
替换,查找,验证,分割
字符串操作
-
查找字符串中的数字;
-
正则如何如实现
在一个字符串中提取数字
let reg = /\d+/g; let arr = str.match(reg); console.log(arr);
正则的创建
-
字面量创建
1.字面量创建 let str = "abc1231dfaf123213fda"; // let reg = /\d+/g; // let abc = "1231" let reg = /abc/g; let res = str.match(reg); console.log(res);
-
通过构造函数
转义字符要加\\d
// 2.构造函数创建 let str = "abc1231dfaf123213fda"; // let reg = new RegExp("\\d+","g"); let abc = "1231"; let reg = new RegExp(abc,"g"); let res = str.match(reg); console.log(res
正则的匹配方法
字符串方法
-
match
let str = "abc11defghiej222k"; let reg = /\d+/g; console.log( str.match(reg) );
-
search
返回索引值,这个会忽略全局匹配。没有就返回-1
let str = "abcdefghiejk"; // let reg = /e/g; let reg = /z/; console.log( str.search(reg) );
-
replace
敏感词过滤
let str = "abc11defghiej222k"; let reg = /\d/g; // console.log( str.replace(reg,"*") ); //arg 匹配的字符,第二个参数是分组 ...参考mdn let res = str.replace(reg,function(arg){ console.log(arg) return "*" }) console.log(res);
-
split
let str = "abc123fda1234rt"; // let arr = str.split(1); let arr = str.split(/\d+/);
正则对象下的方法
-
test 测试是否能匹配
-
exec 每次匹配成功一次然后停止,记录索引位置,然后再次调用的时候,会根据上次结束的位置进行匹配
let str = "abc123fda123"; // let reg = /\d+/g; let reg = /efg/g; console.log( reg.test(str) ); let str = "abc123fda1234"; let reg = /\d+/g; console.log( reg.exec(str) ) console.log(reg.lastIndex); console.log( reg.exec(str) ) console.log( reg.exec(str) )
元字符
-
正则表达式中有特殊含义的非字母字符;
字符类别(Character Classes)
-
\
- 转义符,它有两层含义
- 表示下一个具有特殊含义的字符为字面值
- 表示下一个字符具有特殊含义(转义后的结果是元字符内约定的)
- 转义符,它有两层含义
-
字符相关的元字符
\w
匹配任意一个(字母、数字、下划线)的字符\W
匹配任意一个非(字母、数字、下划线)的字符\s
匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格\S
匹配一个非空白符\d
匹配任意一个阿拉伯数字的字符\D
匹配任意一个非阿拉伯数字的字符.
- 匹配行结束符(\n 是回车 \r 是换行 \u2028 行分隔符 或 \u2029 段落分隔符)以外的任意单个字符都可以匹配到
- 在
字符集合(Character Sets)
中,.将失去其特殊含义,表示的是原始值
-
数量相关的
-
{}
-
x{n}
- n 是一个正整数。前面的模式 x 连续出现 n 次时匹配
-
x{n,m}
- n 和 m 为正整数。前面的模式 x 连续出现至少 n 次,至多 m 次时匹配
- n~m次出现
-
x{n,}
-
n 是一个正整数。前面的模式 x 连续出现至少 n 次时匹配
let str = "abceeeeeeeeeeeffd"; // let reg = /ce{3}f/g; // let reg = /ce{1,4}f/g; // let reg = /ce{1,}f/g console.log( reg.test(str) );
-
-
-
x*
- 匹配前面的模式 x 0 或多次
-
x+
- 匹配前面的模式 x 1 或多次。等价于 {1,}
-
x?
-
匹配前面的模式 x 0 或 1 次
// ? --> {0,1} + ---> {1,} * ---> {0,}; let str = "my name is lilei"; let reg = /my\s+name/g; console.log( reg.test(str)); let str = "123456789"; // let reg = /\d{2,4}/g; //贪婪匹配 let reg = /\d{2,4}?/g; // 惰性匹配; let res = str.match(reg); console.log(res)
-
-
x|y
- 匹配 x 或 y
-
-
位置相关
-
^
- 匹配输入开始。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处
-
$
-
匹配输入结尾。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处
let str = "abedef"; let reg =/^\w/g; let res = str.replace(reg,"*"); console.log(res); let str = "abedef"; let reg =/\w$/g; let res = str.replace(reg,"*"); console.log(res);
-
-
\b
- 匹配一个零宽单词边界(zero-width word boundary)
-
\B
- 匹配一个非零宽单词边界(zero-width word boundary)
// 边界: 非\w 的 都是边界; let str = "this is a book"; let reg = /\bis\b/g; let res = str.match(reg); console.log(res); // \B 非边界; let str = "this is a book"; let reg = /\B\w{2}\b/g; let res = str.match(reg); console.log(res);
-
字符集合 []
[xyz]
-
一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符'-'指定一个范围
-
[xyz]
是一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符 -
[^0-9] 表示非数字 这里面的^ 是非的意思
// []:字符集合; let str = "My name is LiL1ei"; // let reg = /Li[Ll]ei/g; // [a-z] [A-Z]; //[a-Z] 错误 askii 码来的 // let reg = /[0-9]/g; // console.log( reg.test(str)); let reg = /[^0-9]/g; console.log( reg.test(str)); // \d == [0-9]; \w ==[a-zA-Z0-9_];
分组 () 括号相关
-
(子项)
-
可以使用 () 对表达式进行分组,类似数学中分组,也称为子项
let str = "abababfdsafds"; let reg = /(ab){3}/g; console.log(reg.test(str));
-
捕获匹配
-
具有捕获(capturing)特性,即会把匹配结果保存到(子项结果)中
-
(x)
let str = "2020-01-02"; let reg = /(\d{4})-(\d{2})-(\d{2})/; // console.log( ); str.match(reg) console.log(RegExp.$1) console.log(RegExp.$2) console.log(RegExp.$3)
-
-
替换值
-
//字面量 let str = "2020-01-02"; // 01/02/2020 let reg = /(\d{4})-(\d{2})-(\d{2})/; let res = str.replace(reg,"$2/$3/$1"); //方法 let res = str.replace(reg,function(arg,year,mouth,date){ return mouth +"/" + date + "/" +year; });
-
-
反向引用 \n
有时候前面匹配到的规则,后面也要使用
-
这里的 n 表示的是一个变量,值为一个数字,指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串
-
let className = "news-container-nav"; //news_container_nav // \n 在\1 哪里,表示匹配第一个分组就是 (-|_) let reg = /\w{4}(-|_)\w{9}(\1)\w{3}/; let res = reg.test(className); console.log(res);
-
-
索引分组
-
命名分组
-
(?...) 名字
-
groups属性 下面有命名的分组
let str = "2020-01-06"; let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; console.log( str.match(reg));
-
-
非捕获匹配
- 不具有捕获(capturing)特性,即不会把匹配结果保存到(子项结果)中
- (?:x)
-
零宽断言/预查(Assertions)
- 用于指定查找在某些内容(但并不包括这些内容)之前或之后的内容
- 正向零宽断言/预查
- 肯定
- (?=pattern)
- 否定
- (?!pattern)
- 肯定
- 负向零宽断言/预查(注意:ES2018新增)
- 肯定
- (?<=pattern)
- 否定
- (?<!patten)
- 肯定
-
捕获与零宽断言的区别
- 捕获:匹配的内容出现在结果中但不出现在子项结果中
- 零宽断言:完全不会出现在结果
正向零宽断言;替换前面的iphone let str = "iphone3iphone4iphone5iphonenumber"; // 肯定 // let reg = /iphone(?=\d)/g; // 否定 let reg = /iphone(?!\d)/g; let res = str.replace(reg,"苹果"); console.log(res); // 负向零宽断言;替换后面的px let str = '10px20px30pxipx'; // 肯定 // let reg = /(?<=\d+)px/g; // 否定 let reg = /(?<!\d+)px/g; let res = str.replace(reg,"像素"); console.log(res);
匹配模式
-
g
- global,全局模式:找到所有匹配,而不是在第一个匹配后停止
-
i
- ignore,忽略大小写模式:匹配不区分大小写
-
m
-
multiple,多行模式:将开始和结束字符(^和$)视为在多行上工作,而不只是匹配整个输入字符串的最开始和最末尾处
-
let str = `abc efg hij`; let reg = /^\w/gm; let res = str.replace(reg,"*"); console.log(res);
-
-
s
-
dotAll / singleline模式:. 可以匹配换行符
s : 让"."; let str = `abc efg`; let reg = /^a.*g$/gs; console.log( reg.test(str));
-
-
u
-
unicode,unicode模式:匹配unicode字符集
-
{}表示unicode编码
let str = "a"; let reg = /\u{61}/gu; console.log(reg.test(str));
-
-
y
-
sticky,粘性模式:匹配正则中lastIndex属性指定位置的字符,并且如果没有匹配也不尝试从任何后续的索引中进行匹配
-
必须连续匹配。不然就匹配不到
let str = "12345fdafdsa4324"; let reg = /\d/gy; //4324 匹配不到了 console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str));
-
-