JS: RegExp(正则表达式)
regexp语法(包含es2018标准)
注意:本次所有代码都仅在chrome 70中进行测试
-
正则表达式是什么?
正则表达式是用于匹配字符串中字符组合的模式。(mdn)
简单来说,正则表达式是用来提取、捕获文本(匹配字符)的。
-
创建:
-
字面量:
let regex = / pattern / flags
let regex1 = /foo/i;
-
构造函数:
let regex = new regexp(pattern, falgs);
let regex2 = new regexp('bar', ig); // es5 let regex3 = new regexp(/bat/im); // es5 let regex4 = new regexp(/cat/ig, 'g'); // es6 /* regex4 创建方法在es5中会抛出typeerror,因为第一个参数已经是一个正则表达式,而es5不允许此时再使用第二个参数添加修饰符。es6则允许这种写法,但第二个参数会作为修饰符覆盖第一个参数中的修饰符。*/ console.log(regex4); // /cat/g
-
-
实例属性:
每个正则表达式实例都拥有下面的属性,以便获取实例模式的信息。
global:布尔值,表示是否设置了 g(全局匹配)标志。
ignorecase:布尔值,表示是否设置了 i(忽略大小写)标志。
multiline:布尔值,表示是否设置了 m(多行)标志。
unicode:布尔值,表示是否设置了 u(识别 unicode 字符中大于
\uffff
的 unicode 字符)标志。sticky:布尔值,表示是否设置了 y(粘连)标志。
lastindex:上次成功匹配后的索引位置,会成为下次匹配的开始索引位置,只在全局匹配或粘滞匹配模式下可用。
source:正则表达式中
pattern
(模式)的字符串表示,与调用tostring()
或者valueof()
方法得到的结果并不一样。flags:返回正则表达式中
flags
(修饰符)的字符串表示。-
dotall:返回一个布尔值,表示是否设置了 s(dotall)标志。
let str2 = 'batfoocat'; let pattern2 = /at/g; pattern2.global; // true pattern2.sticky; // false pattern2.source; // at pattern2.flags; // g pattern2.tostring(); // /at/g pattern2.valueof(); // /at/g pattern2.lastindex; // 0 let matches = pattern2.exec(str2); // 第一次 matches[0]; // at matches.index; // 1 pattern2.lastindex; // 3 matches = pattern2.exec(str2); // 第二次 matches[0]; // at matches.index; // 7 pattern2.lastindex; // 9 /*第三次会出现报错,是因为已经没有匹配项了,exec()方法返回了null,再执行第四次就会返回第一次匹配的结果,即重新开始匹配*/ matches = pattern2.exec(str2); // 第三次 matches[0]; // error matches.index); // error pattern2.lastindex; // 0
补充:已经废弃的属性(https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/deprecated_and_obsolete_features)
这些废弃的特性仍然可以使用,但你要保持谨慎,因为它们很可能会在未来的某个时候被删除.(mdn)
-
方法:
-
exec
:在指定字符串中进行匹配字符,每次只会返回一个匹配项的信息。匹配成功,则返回一个数组,并更新正则表达式实例的属性,否则返回 null。
返回的数组是 arrary 实例,但包含了两个属性:index(匹配项在字符串中的位置)和 input(正则表达式进行匹配的字符串),数组第一项(下标0)存放匹配到的文本。
注意:如果使用了全局匹配(g),再次使用
exec()
方法会返回第二个匹配项的信息,否则无论使用多少次exec()
方法都只会返回第一个匹配项信息。补充:es2018在返回数组中新增了一个属性
groups
(命名捕获组的信息)let str1 = 'batfoocat'; let pattern1 = /at/g; pattern1.exec(str1); // 第一次 // ["at", index: 1, input: "batfoocat", groups: undefined] pattern1.exec(str1); // 第二次 // ["at", index: 7, input: "batfoocat", groups: undefined] pattern1.exec(str1); // 第三次 // null // 第四次会重新开始匹配,即返回第一次匹配的结果
-
test()
:测试当前正则表达式是否能匹配目标字符串,返回布尔值。let str3 = 'batfoocat'; let str4 = 'abcde'; let pattern3 = /at/g; pattern3.test(str3); // true pattern3.test(str4); // false
-
string.prototype.search()
:检索与正则表达式相匹配的子字符串,匹配成功返回第一个匹配项在字符串中的下标,否则返回-1。let str5 = 'abcdea'; str5.search(/a/g); // 0 str5.search(/f/g); // -1
-
string.prototype.match()
:检索与正则表达式相匹配的子字符串,匹配成功返回一个存放所有匹配项的数组,否则返回null,如果正则表达式中没有标志 g(全局标志),那么match()
方法就只能执行一次匹配。注意:在全局检索模式下,match() 即不提供与子表达式匹配的文本的信息,也不声明每个匹配子串的位置。如果需要这些全局检索的信息,可以使用
regexp.exec()
。let str6 = 'abcdea'; str6.match(/a/g); // ["a", "a"] str6.match(/a/); // ["a", index: 0, input: "abcdea", groups: undefined] str6.match(/f/g); // null
-
string.prototype.replace(regexp, replacement)
:替换一个与正则表达式匹配的子串。let str7 = 'batfoocat'; let a = str7.replace(/at/g, 'oo'); // "boofoocoo" let b = str7.replace(/at/, 'oo'); // "boofoocat" let c = str7.replace(/at/g, (value)=> { return '!' + value; }); // "b!atfooc!at"
-
string.prototype.split(separator [, howmany])
:把一个字符串分割成字符串数组,第二个参数为可选,该参数可指定返回的数组的长度,不填则返回所有。let str8 = 'batfoocat'; let a = str8.split(/at/g); // ["b", "fooc", ""] let b = str8.split(/at/); // ["b", "fooc", ""] let c = str8.split(/at/, 2); // ["b", "fooc"]
-
-
修饰符(标志 - flags):
-
g:全局匹配,找到所有匹配,而不是在发现第一个匹配项后立即停止。
let str9 = 'batfoocat'; str9.match(/at/); // ["at", index: 1, input: "batfoocat", groups: undefined] str9.match(/at/g); // ["at", "at"]
-
i:忽略大小写。
let str10 = 'aabbccdd'; str10.match(/a/gi); // ["a", "a"] str10.match(/a/g); // ["a"] str10.match(/a/g); // ["a"]
-
m:执行多行匹配,和
^
和$
搭配起来使用。多行; 将开始和结束字符(^和$)视为在多行上工作(也就是,分别匹配每一行的开始和结束(由 \n 或 \r 分割),而不只是只匹配整个输入字符串的最开始和最末尾处。(mdn)
` abc def `.match(/def/); // ["def", index: 5, input: "↵abc↵def↵", groups: undefined] ` abc def `.match(/def/m); // ["def", index: 5, input: "↵abc↵def↵", groups: undefined] ` abc def `.match(/^def$/); // null ` abc def `.match(/^defc$/m); // ["def", index: 5, input: "↵abc↵def↵", groups: undefined]
-
u:unicode 模式,可以正确处理码点大于
\uffff
的 unicode 字符。/\u{20bb7}/.test('
-