ES6正则表达式扩展笔记


Posted in Javascript onJuly 25, 2017

 前面的话

正则表达式是javascript操作字符串的一个重要组成部分,但在以往的版本中并未有太多改变。然而,在ES6中,随着字符串操作的变更, ES6也对正则表达式进行了一些更新。本文将详细介绍ES6正则表达式扩展

构造函数

在 ES5 中,RegExp构造函数的参数有两种情况。

第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag)

var regex = new RegExp('xyz', 'i');
// 等价于
var regex = /xyz/i;

第二种情况是,参数是一个正则表示式,这时会返回一个原有正则表达式的拷贝

var regex = new RegExp(/xyz/i);
// 等价于
var regex = /xyz/i;

但是,ES5 不允许此时使用第二个参数添加修饰符,否则会报错

// Uncaught TypeError: Cannot supply flags when constructing one RegExp from another
var regex = new RegExp(/xyz/, 'i');

ES6 改变了这种行为。如果RegExp构造函数第一个参数是一个正则对象,那么可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符

console.log(new RegExp(/abc/ig, 'i').flags);//i

上面代码中,原有正则对象的修饰符是ig,它会被第二个参数i覆盖

【flags】

ES6 为正则表达式新增了flags属性,会返回正则表达式的修饰符

//ES5的source属性返回正则表达式的正文
/abc/ig.source//"abc"
// ES6的flags属性返回正则表达式的修饰符
/abc/ig.flags//'gi'

正则方法

字符串对象共有4个方法,可以使用正则表达式:match()、replace()、search()和split()

ES6 将这4个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上

String.prototype.match 调用 RegExp.prototype[Symbol.match]
String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
String.prototype.search 调用 RegExp.prototype[Symbol.search]
String.prototype.split 调用 RegExp.prototype[Symbol.split]

u修饰符

正则表达式可以完成简单的字符串操作,但默认将字符串中的每一个字符按照16位编码处理。为了解决这个问题, ES6 对正则表达式添加了u修饰符,含义为“Unicode模式”,用来正确处理大于\uFFFF的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码

/^\uD83D/u.test('\uD83D\uDC2A') // false
/^\uD83D/.test('\uD83D\uDC2A') // true

一旦为正则表达式设置了 u 修饰符,正则表达式将会识别32位的辅助平面字符为1个字符,而不是两个

【点号】

点(.)字符在正则表达式中,含义是除了换行符以外的任意单个字符。对于码位大于0xFFFF的 Unicode 字符,点字符不能识别,必须加上u修饰符

var text = "?" ;
console.log(text.length); // 2
console.log(/^.$/.test(text));//false
console.log(/^.$/u.test(text)); //true

【大括号】

ES6 新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词

/\u{61}/.test('a') // false
/\u{61}/u.test('a') // true
/\u{20BB7}/u.test('?') // true

【量词】

使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符

/a{2}/.test('aa') // true
/a{2}/u.test('aa') // true
/?{2}/.test('??') // false
/?{2}/u.test('??') // true

【预定义模式】

u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的 Unicode 字符

/^\S$/.test('?') // false
/^\S$/u.test('?') // true

【字符串长度】

上面代码的\S是预定义模式,匹配所有不是空格的字符。只有加了u修饰符,它才能正确匹配码点大于0xFFFF的 Unicode 字符

虽然ES6不支持字符串码位数量的检测,length属性仍然返回字符串编码单元的数量。利用[\s\S],再加上u修饰符,就可以写出一个正确返回字符串长度的函数

function codePointLength(text) {
 var result = text.match(/[\s\S]/gu);
 return result ? result.length : 0;
}
var s = '??';
console.log(s.length); // 4
console.log(codePointLength(s)); // 2

【检测支持】

u修饰符是语法层面的变更,尝试在不兼容 ES6 的 JS 引擎中使用它会抛出语法错误。如果要检测当前引擎是否支持u修饰符,最安全的方式是通过以下函数来判断

function hasRegExpU() {
  try {
    var pattern = new RegExp(".", "u");
    return true;
  } catch (ex) {
    return false;
  }
}

这个函数使用了RegExp构造函数并传入字符串'u'作为参数,该语法即使在旧版 JS 引擎中也是有效的。但是,如果当前引擎不支持u修饰符则会抛出错误

y修饰符

除了u修饰符,ES6 还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符

y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义

【全局匹配】

y修饰符的设计本意,就是让头部匹配的标志^在全局匹配中都有效

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;
console.log(r1.exec(s)); // ["aaa"]
console.log(r2.exec(s)); // ["aaa"]
console.log(r1.exec(s)); // ["aa"]
console.log(r2.exec(s)); // null

上面代码有两个正则表达式,一个使用g修饰符,另一个使用y修饰符。这两个正则表达式各执行了两次,第一次执行的时候,两者行为相同,剩余字符串都是_aa_a。由于g修饰没有位置要求,所以第二次执行会返回结果,而y修饰符要求匹配必须从头部开始,所以返回null。

如果改一下正则表达式,保证每次都能头部匹配,y修饰符就会返回结果了

var s = 'aaa_aa_a';
var r = /a+_/y;
console.log(r.exec(s)); // ["aaa_"]
console.log(r.exec(s)); // ["aa_"]

上面代码每次匹配,都是从剩余字符串的头部开始

【非全局匹配】

单单一个y修饰符使用match方法,只能返回第一个匹配,必须与g修饰符联用,才能返回所有匹配

'a1a2a3'.match(/a\d/y) // ["a1"]
'a1a2a3'.match(/a\d/gy) // ["a1", "a2", "a3"]

[注意]y修饰符只有在调用 exec()和test()这两个正则匹配方法时,才会进行全局匹配;如果调用match()、replace()等字符串的方法时,不会进行全局匹配

【stiky属性】

与y修饰符相匹配,ES6 的正则对象多了sticky属性,表示是否设置了y修饰符

var r = /hello\d/y;
r.sticky // true

【应用】

y修饰符的一个应用,是从字符串提取 token(词元),y修饰符确保了匹配之间不会有漏掉的字符

const TOKEN_Y = /\s*(\+|[0-9]+)\s*/y;
const TOKEN_G = /\s*(\+|[0-9]+)\s*/g;
tokenize(TOKEN_Y, '3 + 4')// [ '3', '+', '4' ]
tokenize(TOKEN_G, '3 + 4')// [ '3', '+', '4' ]
function tokenize(TOKEN_REGEX, str) {
 let result = [];
 let match;
 while (match = TOKEN_REGEX.exec(str)) {
  result.push(match[1]);
 }
 return result;
}

上面代码中,如果字符串里面没有非法字符,y修饰符与g修饰符的提取结果是一样的。但是,一旦出现非法字符,两者的行为就不一样了

tokenize(TOKEN_Y, '3x + 4')
// [ '3' ]
tokenize(TOKEN_G, '3x + 4')
// [ '3', '+', '4' ]

上面代码中,g修饰符会忽略非法字符,而y修饰符不会,这样就很容易发现错误

【检测支持】

y修饰符与u修饰符类似,它也是一个语法层面的变更,尝试在不兼容 ES6 的 JS 引擎中使用它会抛出语法错误。如果要检测当前引擎是否支持y修饰符,可以通过以下函数来检测

function hasRegExpY() {
  try {
    var pattern = new RegExp(".", "y");
    return true;
  } catch (ex) {
    return false;
  }
}

这个函数使用了RegExp构造函数并传入字符串'y'作为参数,该语法即使在旧版 JS 引擎中也是有效的。但是,如果当前引擎不支持y修饰符则会抛出错误

总结

以上所述是小编给大家介绍的ES6正则表达式扩展笔记,希望对大家有所帮助,如果大家有任何疑问请给我留

言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 调试器简介
Feb 21 Javascript
js Array对象的扩展函数代码
Apr 24 Javascript
js加密解密字符串可自定义密码因子
May 13 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
Feb 25 Javascript
jQuery获取某天的农历日期并判断是否除夕或新年的方法
Mar 01 Javascript
DIV+CSS+jQ实现省市联动可扩展
Jun 22 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
Aug 12 Javascript
超详细的JS弹出窗口代码大全
Apr 18 Javascript
详解Angular路由 ng-route和ui-router的区别
May 22 Javascript
Vue的click事件防抖和节流处理详解
Nov 13 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 Javascript
在Vue中获取自定义属性方法:data-id的实例
Sep 09 Javascript
简单实现js拖拽效果
Jul 25 #Javascript
Vue实现一个返回顶部backToTop组件
Jul 25 #Javascript
基于jquery实现多级菜单效果
Jul 25 #jQuery
关于TypeScript中import JSON的正确姿势详解
Jul 25 #Javascript
微信JSSDK调用微信扫一扫功能的方法
Jul 25 #Javascript
利用node.js爬取指定排名网站的JS引用库详解
Jul 25 #Javascript
详解angularjs获取元素以及angular.element()用法
Jul 25 #Javascript
You might like
ajax php传递和接收变量实现思路及代码
2012/12/19 PHP
利用phpExcel实现Excel数据的导入导出(全步骤详细解析)
2013/11/26 PHP
php+jQuery+Ajax简单实现页面异步刷新
2016/08/08 PHP
PHP实现找出有序数组中绝对值最小的数算法分析
2017/08/07 PHP
类似框架的js代码
2006/11/09 Javascript
fromCharCode和charCodeAt 方法
2006/12/27 Javascript
用正则获取指定路径文件的名称
2007/02/27 Javascript
js以对象为索引的关联数组
2010/07/04 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
2012/02/02 Javascript
JS特权方法定义作用以及与公有方法的区别
2013/03/18 Javascript
JSON中双引号的轮回使用过程中一定要小心
2014/03/05 Javascript
js兼容火狐显示上传图片预览效果的方法
2015/05/21 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
AngularJS使用指令增强标准表单元素功能
2016/07/01 Javascript
原生Javascript和jQuery做轮播图简单例子
2016/10/11 Javascript
JavaScript下拉菜单功能实例代码
2017/03/01 Javascript
微信公众号菜单配置微信小程序实例详解
2017/03/31 Javascript
Js面试算法详解
2018/04/08 Javascript
Layui组件Table绑定行点击事件和获取行数据的方法
2018/08/19 Javascript
[53:50]CHAOS vs Mineski 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
Python使用BeautifulSoup库解析HTML基本使用教程
2016/03/31 Python
Python中的CSV文件使用"with"语句的方式详解
2018/10/16 Python
python获取地震信息 微信实时推送
2019/06/18 Python
python 实现GUI(图形用户界面)编程详解
2019/07/17 Python
python 实现的车牌识别项目
2021/01/25 Python
CSS3中利用animation属性创建雪花飘落特效
2014/05/14 HTML / CSS
CSS3田字格列表的样式编写方法
2018/11/22 HTML / CSS
HTML5之SVG 2D入门7—SVG元素的重用与引用
2013/01/30 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
Seavenger官网:潜水服、浮潜、靴子和袜子
2020/03/05 全球购物
哈弗商学院毕业生求职信
2014/02/26 职场文书
法学求职信
2014/06/22 职场文书
2014年教师节演讲稿范文
2014/09/10 职场文书
导游词300字
2015/02/13 职场文书
交通事故责任认定书
2015/08/06 职场文书