- 参数一:字符串 | 正则
- 参数二:修饰符
var regex = new RegExp('xyz', 'i');
// 等价于
var regex = new RegExp(/xyz/i) // ES5
// 等价于
var regex = /xyz/i;
var regex = new RegExp(/xyz/i, 'i') // ES6
- match
- replace
- search
- split
ES6 对正则表达式添加了u修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。
// 正确返回字符串长度
function codePointLength(text) {
var result = text.match(/[\s\S]/gu);
return result ? result.length : 0;
}
var s = '𠮷𠮷';
s.length // 4
codePointLength(s) // 2
y修饰符,叫做“粘连”(sticky)修饰符。为了让头部匹配的标志^在全局匹配中都有效。
/b/y.exec('ba')
// null
/b/y.exec('aba')
// null
点(.)是一个特殊字符,代表任意的单个字符,两个例外
- 四个字节的 UTF-16 字符(u修饰符解决)
- 行终止符
- U+000A 换行符(\n)
- U+000D 回车符(\r)
- U+2028 行分隔符(line separator)
- U+2029 段分隔符(paragraph separator)
// .不匹配\n
/foo.bar/.test('foo\nbar') // false
/foo.bar/s.test('foo\nbar') // true
dotAll模式,即点(dot)代表一切字符。
- RegExp.prototype.unicode 属性:u修饰符
- RegExp.prototype.sticky 属性:y修饰符
- RegExp.prototype.dotAll 属性:s修饰符
- RegExp.prototype.flags 属性:正则表达式的所有修饰符
var r = /abc/u;
r.unicode // true
var r = /abc/y;
r.sticky // true
var r = /abc/s;
r.dotAll // true
// ES5 的 source 属性:正则表达式的正文
/abc/ig.source
// "abc"
// ES6 的 flags 属性:正则表达式的修饰符
/abc/ig.flags
// 'gi'
- 先行断言:x只有在y前面才匹配,必须写成/x(?=y)/
- 先行否定断言:x只有不在y前面才匹配,必须写成/x(?!y)/
- 后行断言:x只有在y后面才匹配,必须写成/(?<=y)x/
- 后行否定断言:x只有不在y后面才匹配,必须写成/(?<!y)x/ 括号不计入返回结果的
/\d+(?=%)/.exec('100% of US presidents have been male') // ["100"]
/\d+(?!%)/.exec('that’s all 44 of them') // ["44"]
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill') // ["100"]
/(?<!\$)\d+/.exec('it’s is worth about €90') // ["90"]
注意:贪婪模式
- 正常情况:从左到右
- 后行断言:从右到左
/^(\d+)(\d+)$/.exec('1053') // ["1053", "105", "3"]
/(?<=(\d+)(\d+))$/.exec('1053') // ["", "1", "053"]
允许正则表达式匹配符合 Unicode 某种属性的所有字符。
- \p{...}:匹配
- \P{...}:不匹配
var regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π') // true
const regexGreekSymbol = /\P{Script=Greek}/u;
regexGreekSymbol.test('啊') // true
给匹配加上ID
const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj[1]; // 1999
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31
// ES2018
const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31
const {year, month, day} = matchObj.groups
'2015-01-02'.replace(RE_DATE, '$<day>/$<month>/$<year>') // 2015/01/02
特点:
- 替换:replace 函数新增了一个参数groups
- 引用具名组匹配
- \k<组名>
- \1
let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
'2015-01-02'.replace(re, (
matched, // 整个匹配结果 2015-01-02
capture1, // 第一个组匹配 2015
capture2, // 第二个组匹配 01
capture3, // 第三个组匹配 02
position, // 匹配开始的位置 0
S, // 原字符串 2015-01-02
groups // 具名组构成的一个对象 {year, month, day}
) => {
let {day, month, year} = groups;
return `${day}/${month}/${year}`;
});
// 引用具名组匹配:\k<组名>
const RE_TWICE = /^(?<word>[a-z]+)!\k<word>$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false
// 引用具名组匹配:\1
const RE_TWICE = /^(?<word>[a-z]+)!\1$/;
RE_TWICE.test('abc!abc') // true
RE_TWICE.test('abc!ab') // false