当ES6赶上 字符串和正则表达式

写在前面

字符串是一种重要的数据类型,而正则表达式则是赋予了编程人员更多操做字符串的能力。ES6的创做者为字符串和正则表达式添加了许多的新功能。下面玲珑未来进行一个全面的总结。html

字符串和正则两个部分各两节,全文阅读时间大约10分钟es6

字符串

1.更好的Unicode支持

Unicode是一个字符集。将全世界全部的字符包含在一个集合里,计算机只要支持这一个字符集,就能显示全部的字符,不再会有乱码了。正则表达式

在es6出现以前,js字符串一直基于16位字符编码进行构建。每16位序列是一个编码单元,表明一个字符,Unicode0引入扩展字符集,16位字符编码将再也不包含任何字符。编码规则也所以变动。编程

对于UTF-16来讲,码位能够有多个编码单元表示,是表示不是组成。数组

对于UTF-16前2^16个码位都是16位的编码单元表示,这个范围被称做基本多文种平面BMP,当超过期,引入代理对,规定用两个16位编码单元表示一个码位,即32位辅助平面字符。一个32位代理对表示字符长度为1,可是length属性值为2.bash

若是想进一步了解他能够参考阮一峰的一片日志:www.ruanyifeng.com/blog/2014/1… 日志里面说到的码点就是码位函数

1.1codePointAt(0)方法

在es6以前,charCodeAt()方法返回字符每一个16位编码单元对应的数值,再在es6中新增了codePointAt方法,codePointAt(0)返回的是位置0处的码点或者说是位置0处的码位,包含多个编码单元>16进制上限FFFF,charCodeAt(0)方法返回的是位置0的第一个编码单元.ui

所以能够用此方法判断一个字符占用编码单元的数量编码

function is32Bit(c) {
    
    return c.codePointAt(0) > 0xFFFF;
}
console.log(is32Bit("吉利"));  //true
console.log(is32Bit("a"));    //false
复制代码

1.2 String.fromCodePoint()方法

codePointAt()方法在字符串中检索一个字符串的码位,也可使用String.fromCodePoint()方法根据指定的码位生成一个字es5

console.log(String.fromCodePoint(134071));   //吉
复制代码

1.3normalize()方法

在比较字符或者进行排序的时候,可能出现等价的状况,然而等价却存在两种状况

  • 规范的等效是不管从哪一个角度来看,两个序列的码位都是没有区别的
  • 兼容的码位序列看起来不一样,可是在特定的状况下能够交换使用。 可是在严格模式下不是等效的,除非经过某些方法把这种等效关系标准化

normalize()方法提供Unicode的标准化形式,,这个方法能够接受一个可选的字符串参数。Unicode标准化形式有四种

  • 以标准等价方式分解,而后以标准等价方式重组(“NFC”),默认值选项
  • 以标准等价方式分解(“NFD”)
  • 以兼容等价方式分解(“NFKC”)
  • 以兼容方式分解,而后以标准等价方式重组

1.4 正则表达式u修饰符

正则表达式后添加u修饰符会将编码单元模式切换成字符模式,这个时候的代理对不会被视为两个字符。

可是length这个属性返回的仍然是字符串编码单元的数量,而不是码位的数量。可是也能够经过带u修饰符的正则表达式来解决这个问题。

function codePointerLength(text) {
    let result = text.match(/[\s\S]/gu);
    return result ? result.length:0;
}
console.log(codePointerLength("吉abc")); //4

复制代码

检测是否支持u修饰符

u修饰符在不兼容ES6的JavaScript引擎中使用会致使语法错误,能够经过如下函数检测是否支持。

function hasRegExpU() {
    try{
        var pattern = new Regexp(".","u");
        return ture;
    }catch (ex) {
        return false;
    }
}
复制代码

2.其余字符串的变动

2.1字符串中的字串识别

开发者们用indexOf()方法在一段字符串中检测另外一段子字符串。在es6中提供3个方法达到相似的效果

  • startWith()方法,在字符串起始部分检测指定文本返回true,不然返回false。
  • incledes()方法,若是在字符串中检测到指定文本返回true,不然返回false。
  • endWith()方法,顾名思义在末尾检测,用法与上面一致。

上面三个方法接受两个参数,第1个参数是指定要搜索的文本是一个字符。第2个是开始搜索位置的索引值是一个数字。不指定第二个参数endwith通常从字符串末尾处开始匹配。示范以下

let mes = "hello world";

console.log(mes.startWith("hello"));
console.log(mes.endWith("!"));
console.log(mes.includes("o"));

console.log(mes.startWith("o"));
console.log(mes.endWith("d!"));
console.log(mes.includes("x"));

console.log(mes.startWith("o",4));
console.log(mes.endWith("o",8));
console.log(mes.includes("o",8));
//9个结果依次为:true true true   false true false    true true false
复制代码

console.log(mes.endWith("o",8));会从第7位第二个o开始匹配。索引值-要搜索文本的长度=8-1

2.2 repeat()方法

es6为字符串新增长的repeat()方法,接受一个number类型的参数,返回重复该次数的一个新字符串。

console.log(x.repeat(3)); //"xxx"

复制代码

我是2条分割线,嘎嘎嘎

正则表达式

1.其余正则表达式的变动

1.1正则表达式y修饰符

y修饰符粘滞正则表达式,从正则表达式的lastIndex属性开始进行。若是指定位置没有匹配成功那么将中止匹配并返回结果。

let text =  'hello1 hello2 hello3';
let patt = /hello\d\s?/,
    result = patt.exec(text);
let gPatt = /helllo\d\s?/g,
    gResult = gPatt.exec(text);
let yPatt = /hello\d\s?/y,
    yResult = yPatt.exec(text);
    
console.log(resut[0]);   //"hello1 "
console.log(gResut[0]);   //"hello1 "
console.log(yResut[0]);   //"hello1 "

patt.lastIndex = 1;
gPatt.lastIndex = 1;
yPatt.lastIndex = 1;

result = patt.exec(text);
gResult = gPatt.exec(text);
yResult = yPatt.exec(text);

console.log(resut[0]);   //"hello1 "
console.log(gResut[0]);   //"hello2 "
console.log(yResut[0]);   //抛出错误

复制代码

这里三个正则表达式中,第一个没有修饰符,第二个全局修饰符g,第三个用了y修饰符。

第一次匹配的时候是从h字符开始匹配。当lastIndex = 1;以后,对于没有修饰符的表达式自动忽略这个变化,结果仍是hello1 ,g修饰符会从e字符开始匹配,输出hello2 ,yResul会从e字符开始匹配,ello h与之不等,最后结果为null,因此会抛出错误。

当执行y修饰符以后,会把上一次匹配最后的一个字符的后一位索引值保存在lastIndex中去,若是执行y修饰符匹配结果为空那么lastIndex值会被重置为0,g修饰符与此相同。

只有调用正则表达式对象的exec()和test()这些方法时才会设计lastIndex属性,如调用字符串的方法natch()就不会触发粘滞行为。

检测y修饰符是否存在能够用sticky属性,若是js引擎支持粘滞修饰符,则stickey属性值为true,不然为false

let patt = /hello\d/y;
console.log(patt.sticky);
复制代码

1.2正则表达式的复制

在es5中,能够给正则表达式的构造函数传递正则表达式做为参数来复制这个正则表达式。但事实第一个参数为正则表达式的时候不能用第二个参数,es6中修改了这个行为,第二个参数能够是修饰符。

let re1 = /ab/i;
let re2 = new RegExp(re1,"g");
console.log(re1.toString());  // "/ab/i"
console.log(re2.toString());  // "/ab/g"
复制代码

1.3flags属性

es6新增的flags属性会返回全部应用于当前正则表达式的修饰符

let re = /ab/g;
console.log(re.source);   //"ab"
console.log(re.flags);    //"g"
复制代码

2.模板字面量

2.1基础语法

一句话归纳,用反撇号(`)代替了双引号,单引号。

若是想在字符串中用反撇号,就用\转义便可。如

let message = `\`hello\`!`;
console.log(message);
复制代码

结果是hello!

2.2简化的多行字符串

在es6以前,经过数组或字符串拼接的方法来建立多行字符串,es6中只须要在代码中直接换行,换行也改变length属性值。同时再反撇号中全部的空格符都属于字符串的一部分。

let message = `Multiline
string`;
console.log(message);
console.log(message.length);   //16=6+9+1
复制代码

2.3 字符串占位符

在一个模板字面量中,你能够把任何合法的JavaScript表达式嵌入到占位符中并将其做为字符串的一部分输出到结果中。

占位符一般由${}组成,中间可包含任何JavaScript表达式。模板字面量自己也是JavaScript表达式,所以在一个模板字面量里面能够嵌入另一个模板字面量。

let name = "sarah";
let message = `my${`name is${name}.`}`;
console.log(message);//my name is sarah.
复制代码

message是一个模板字面量,里面又包含了name is${name}.这个模板字面量。

2.4 标签模板

在模板字面量中使用原始值

经过String.raw标签转换成原生字符串

let message = String.raw`Mul\nddd`;
console.log(message); //"Mul\\nddd"由于\n的原生是\\n.
复制代码

总结

  • es6中codePointAt方法和String.fromCodePoint()方法实现码位和字符串之间的转化。

  • 在比较字符串的时候,normalize()方法能够将字符串标准化,标准化有四种形式,能够更准确地比较字符串

  • 还有新增的一些其余方法检测一个字符串里面的子串,复制字符串。

  • 在es6中的正则这一块,新加了经过构造函数来复制正则表达式的语法,正则表达式中新增的y修饰符,以及用反撇号来代替双,单引号的模板字面量。

相关文章
相关标签/搜索