正则表达式(Regular Expression)
-
总结
- 正则的创建
- 正则的匹配方法
1)正则对象下的方法test、exec
2) 字符串方法match、search、replace、splite
-
匹配模式g、i、m、s、u、y
-
元字符
1)字符相关
2)数量相关
3)位置相关
4)括号相关()、[]
-
分组
正则的创建
-
通过构造函数、字面量创建
// 1. 利用 RegExp对象来创建 正则表达式 var regexp = new RegExp(/123/); console.log(regexp); // 2. 利用字面量创建 正则表达式 var rg = /123/;
正则的匹配方法
正则对象下的方法
-
test,用于检索字符串中指定的值是否符合该规则。返回 true 或 false。
var reg = /123/; console.log(reg.test(123)); //返回true console.log(reg.test('abc')); //返回false -
exec,检索字符串中指定的值。返回找到的值,并确定其位置。
let str = "abc123efg123efg"; let reg = /efg/g; let reg1 = /sd/g; console.log(reg.exec(str)); //返回的是检测到的第一个值,可以多次执行,但每次只能返回一个值 console.log(reg.exec(str)); console.log(reg1.exec(str)); //检索不到返回null //返回 ["efg", index: 6, input: "abc123efg123efg", groups: undefined] ["efg", index: 12, input: "abc123efg123efg", groups: undefined] //多次执行返回的是顺序后面的位置 null
字符串方法
-
match,找到一个或多个正则表达式的匹配。返回值为数组或者null
//在字符串中查找 "ain" var str= "The rain in SPAIN stays mainly in the plain"; var n= str.match(/ain/g); console.log(n); //*n* 输出数组结果值: (3) ["ain", "ain", "ain"] //正则表达式中 let str = "abc11defghiej222k"; let reg = /\d+/g; //匹配全局数字 console.log( str.match(reg) ); //返回 (2) ["11", "222"] -
search,检索与正则表达式相匹配的值, 返回对象起始位置,没找到返回-1
var str = "VisitRunoob!"; var n= str.search("Runoob"); console.log(n); //返回 5 let str = "abcdefghiejk"; let reg1 = /e/g; //返回4 let reg2 = /z/; //返回-1 console.log(str.search(reg1)); console.log(str.search(reg2)); -
replace,替换与正则表达式匹配的子串。
var str = "Visit Microsoft! Visit Microsoft!"; var n = str.replace("Microsoft", "Runoob"); console.log(n); //返回 Visit Runoob! Visit Microsoft! //正则表达式 let str = "abc11defghiej222k"; let reg = /\d/g; console.log( str.replace(reg,"*") ); //将所有数字替换为* //返回 abc**defghiej***k -
split,把字符串分割为字符串数组。
-
提示: 如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
注意: split() 方法不改变原始字符串。
let str = "abc123fda1234rt"; let arr = str.split(1); console.log(arr); //返回 (3) ["abc", "23fda", "234rt"] let arr = str.split(/\d+/); //以数字分割 console.log(arr); //返回 (3) ["abc", "fda", "rt"] -
匹配模式
-
g
- 全局模式:找到所有匹配,而不是在第一个匹配后停止
-
i
- 忽略大小写模式:匹配不区分大小写
-
m
-
multiple,多行模式:将开始和结束字符(^和$)视为在多行上工作,而不只是匹配整个输入字符串的最开始和最末尾处
let str = `abc efg hij`; let reg = /^\w/gm; let res = str.replace(reg,"*"); console.log(res); //返回 *bc *fg *ij
-
-
s
-
dotAll / singleline模式:. 可以匹配换行符
let str = `abc efg`; let reg = /^a.*g$/gs; console.log( reg.test(str)); //返回 true
-
-
u
-
unicode,unicode模式:匹配unicode字符集
let str = "a"; let reg = /\u{61}/gu; console.log(reg.test(str)); //返回 true
-
-
y
-
sticky,粘性模式:匹配正则中lastIndex属性指定位置的字符,并且如果没有匹配也不尝试从任何后续的索引中进行匹配
let str = "123fdafdsa24"; let reg = /\d/g; console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str)); console.log( reg.exec(str)); //返回 ["1", index: 0, input: "123fdafdsa24", groups: undefined] ["2", index: 1, input: "123fdafdsa24", groups: undefined] ["3", index: 2, input: "123fdafdsa24", groups: undefined] ["2", index: 10, input: "123fdafdsa24", groups: undefined]
-
元字符
-
正则表达式中有特殊含义的非字母字符;
-
1.字符相关 2.数量相关 3.位置相关 4.括号相关
预定义类(字符相关)
- .
- 查找单个字符,除了换行和行结束符。
- \
- 转义符,它有两层含义
- 表示下一个具有特殊含义的字符为字面值
- 表示下一个字符具有特殊含义(转义后的结果是元字符内约定的)
- 转义符,它有两层含义
- \d 匹配任意一个阿拉伯数字的字符
- \D 匹配任意一个非阿拉伯数字的字符
- \w 匹配任意一个(字母、数字、下划线)的字符
- \W 匹配任意一个非(字母、数字、下划线)的字符
- \s 匹配一个空白符,包括空格、制表符、换页符、换行符和其他 Unicode 空格
- \S 匹配一个非空白符
量词(数量相关)
-
x*
- 匹配前面的模式 x 0 或多次(包括1次)
-
x+
- 匹配前面的模式 x 1 或多次。等价于 {1,}
-
x?
-
匹配前面的模式 x 0 或 1 次
//贪婪匹配 let str = "123456789"; let reg = /\d{2,4}/g; //没有?,按照最多的匹配 let res = str.match(reg); console.log(res) //返回 (2) ["1234", "5678"] // 惰性匹配; let str = "123456789"; let reg = /\d{2,4}?/g; //有?,按照最少的匹配 let res = str.match(reg); console.log(res) //返回 (4) ["12", "34", "56", "78"] 贪婪匹配 非贪婪匹配 + 一次或多次 +? 只匹配一次 ? 0次或一次 ?? 匹配 0次 * 0次或多次 *? 匹配0次 {n} n次 {n}? 按照n次匹配 {n,} 最少n次 {n,}? 按照n次匹配 {n,m} n到m次 {n,m}? 按照n次匹配
-
-
x|y
- 匹配 x 或 y
-
x{n}
- n 是一个正整数。前面的模式 x 连续出现 n 次时匹配
-
x{n,m}
- n 和 m 为正整数。前面的模式 x 连续出现至少 n 次,至多 m 次时匹配
-
x{n,}
-
n 是一个正整数。前面的模式 x 连续出现至少 n 次时匹配
-
边界符(位置相关)
-
^n
-
匹配任何开头为 n 的字符串。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处
-
-
n$
- 匹配任何结尾为 n 的字符串。。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处
-
\b
-
匹配一个零宽单词边界
//边界,非\w (数字、字母、下划线)的都是边界 let str = "this is a book"; let reg = /\bis\b/g; let res = str.match(reg); console.log(res); //返回 ["is"]
-
-
\B
-
匹配一个非零宽单词边界
let str = "this is a book"; let reg = /\B\w{2}\b/g; let res = str.match(reg); console.log(res); //返回 (2) ["is", "ok"]
-
括号相关
-
()
-
分组
let str = "abababfdsafds"; let reg = /(ab){3}/g; console.log(reg.test(str)); //true let str = "abababfdsafds"; let reg = /ab{3}/g; console.log(reg.test(str)); //false -
提取值
let str = "2020-01-02"; let reg = /(\d{4})-(\d{2})-(\d{2})/; str.match(reg) console.log(RegExp.$1) console.log(RegExp.$2) console.log(RegExp.$3) //返回 2020 01 02 -
替换
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; // }); console.log(res) //返回 01/02/2020 -
反向引用
- \n,这里的 n 表示的是一个变量,值为一个数字,指向正则表达式中第 n 个括号(从左开始数)中匹配的子字符串
// 反向引用; let className = "news-container-nav"; //news_container_nav let reg = /\w{4}(-|_)\w{9}(\1)\w{3}/; //(\1)指向第一个括号(-|_) let res = reg.test(className); console.log(res); //true
-
-
[],字符集合
-
[abc],查找方括号之间的任何字符。
-
[0-9],查找任何从 0 至 9 的数字。
-
[a-z],查找任何从小写 a 到小写 z 的字符。
-
[A-Z],查找任何从大写 A 到大写 Z 的字符。
-
[A-z],查找任何从大写 A 到小写 z 的字符。
-
[^abc],^符号表示取反。
\d 相当于 [0-9]; \w 相当于 [a-zA-Z0-9_];
-
分组
-
(子项)
-
可以使用 () 对表达式进行分组,类似数学中分组,也称为子项
-
索引分组
let str = "2020-01-06"; let reg = /(\d{4})-(\d{2})-(\d{2})/; console.log( str.match(reg)); //返回 (4) ["2020-01-06", "2020", "01", "06", index: 0, input: "2020-01-06", groups: undefined] 0: "2020-01-06" 1: "2020" 2: "01" 3: "06" groups: undefined index: 0 input: "2020-01-06" length: 4 __proto__: Array(0) -
命名分组
-
(?...)
-
groups属性
-
let str = "2020-01-06"; let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; console.log( str.match(reg)); console.log(str.match(reg)[0]); console.log(str.match(reg).groups.year); //查找groups里面的year //返回 (4) ["2020-01-06", "2020", "01", "06", index: 0, input: "2020-01-06", groups: {…}] 0: "2020-01-06" 1: "2020" 2: "01" 3: "06" groups: {year: "2020", month: "01", day: "06"} index: 0 input: "2020-01-06" length: 4 __proto__: Array(0) 2020-01-06 2020
-
-
捕获匹配(分组)
-
具有捕获(capturing)特性,即会把匹配结果保存到(子项结果)中
-
(x)
-
1 var str = '123abc'; 2 var pattern = /(\d{4})(\w+)/; 3 pattern.test(str); 4 console.log(RegExp.$1) //-> 123 5 console.log(RegExp.$2) //-> abc
-
-
非捕获匹配(分组)
-
不具有捕获(capturing)特性,即不会把匹配结果保存到(子项结果)中
-
(?:x)
-
1 var str = '123abc'; 2 var pattern = /(\d{3})(?:\w+)/; 3 pattern.test(str); 4 console.log(RegExp.$1) //-> 123 5 console.log(RegExp.$2) //-> ''
-
-
嵌套匹配(分组)
-
嵌套分组从外向内获取
-
1 var str = 'abc'; 2 var pattern = /(a?(b?(c?)))/; 3 pattern.test(str); 4 console.log(RegExp.$1) //-> abc 5 console.log(RegExp.$2) //-> bc 6 console.log(RegExp.$3) //-> c
-
-
零宽断言(Assertions)
-
用于指定查找在某些内容(但并不包括这些内容)之前或之后的内容
-
零宽度正预测先行断言 (?=exp) //判断正则表达式中?的位置的右边符合表达式的条件。 零宽度负预测先行断言 (?!exp) //判断正则表达式中?的位置的右边不符合表达式的条件。 零宽度正回顾后发断言 (?<=exp) //判断正则表达式中?的位置的左边符合表达式的条件。 零宽度负回顾后发断言 (?<!exp) //判断正则表达式中?的位置的左边不符合表达式的条件。 -
捕获与零宽断言的区别
- 捕获:匹配的内容出现在结果中但不出现在子项结果中
- 零宽断言:完全不会出现在结果