Skip to content

Latest commit

 

History

History
172 lines (146 loc) · 4.5 KB

06正则的扩展.md

File metadata and controls

172 lines (146 loc) · 4.5 KB

正则的扩展

1.RegExp 构造函数

  1. 参数一:字符串 | 正则
  2. 参数二:修饰符
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

2.字符串的正则方法

  1. match
  2. replace
  3. search
  4. split

3.u 修饰符

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

4.y 修饰符

y修饰符,叫做“粘连”(sticky)修饰符。为了让头部匹配的标志^在全局匹配中都有效。

/b/y.exec('ba')
// null

/b/y.exec('aba')
// null

5.s 修饰符:dotAll 模式

点(.)是一个特殊字符,代表任意的单个字符,两个例外

  1. 四个字节的 UTF-16 字符(u修饰符解决)
  2. 行终止符
    • 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)代表一切字符。

6.属性

  1. RegExp.prototype.unicode 属性:u修饰符
  2. RegExp.prototype.sticky 属性:y修饰符
  3. RegExp.prototype.dotAll 属性:s修饰符
  4. 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'

7.后行断言

  1. 先行断言:x只有在y前面才匹配,必须写成/x(?=y)/
  2. 先行否定断言:x只有不在y前面才匹配,必须写成/x(?!y)/
  3. 后行断言:x只有在y后面才匹配,必须写成/(?<=y)x/
  4. 后行否定断言:x只有不在y后面才匹配,必须写成/(?<!y)x/ 括号不计入返回结果的
/\d+(?=%)/.exec('100% of US presidents have been male')  // ["100"]
/\d+(?!%)/.exec('thats all 44 of them')                 // ["44"]
/(?<=\$)\d+/.exec('Benjamin Franklin is on the $100 bill')  // ["100"]
/(?<!\$)\d+/.exec('its is worth about 90')                // ["90"]

注意:贪婪模式

  • 正常情况:从左到右
  • 后行断言:从右到左
/^(\d+)(\d+)$/.exec('1053') // ["1053", "105", "3"]
/(?<=(\d+)(\d+))$/.exec('1053') // ["", "1", "053"]

8.Unicode 属性类

允许正则表达式匹配符合 Unicode 某种属性的所有字符。

  1. \p{...}:匹配
  2. \P{...}:不匹配
var regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π') // true

const regexGreekSymbol = /\P{Script=Greek}/u;
regexGreekSymbol.test('啊') // true

9.具名组匹配

给匹配加上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