ES6第二部分(字符串的扩展、字符串的新增方法、正则的扩展)

本文概述了ES6中字符串和正则表达式的重要更新,包括Unicode字符处理、模板字符串、标签模板、新增字符串方法以及正则表达式的扩展功能。深入探讨了这些特性如何提升开发效率和代码可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

9.字符串的扩展
(1)字符的Unicode表示法
将码点放入大括号,就能正确解读该字符。

"\u{41}\u{42}\u{43}"
// "ABC"

JavaScript共有6种方法可以表示一个字符

'\z' === 'z'  // true
'\172' === 'z' // true
'\x7A' === 'z' // true
'\u007A' === 'z' // true
'\u{7A}' === 'z' // true

(2)字符串的遍历接口
ES6 为字符串添加了遍历器接口,使得字符串可以被for…of循环遍历。

for (let codePoint of 'foo') {
  console.log(codePoint)}
// "f"// "o"// "o"

(3)模板字符串
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

// 普通字符串`In JavaScript '\n' is a line-feed.`
// 多行字符串`In JavaScript this is
 not legal.`
console.log(`string text line 1
string text line 2`);
// 字符串中嵌入变量let name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`

如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。

let greeting = `\`Yo\` World!`;

(4)标签模板
模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。
“标签”指的就是函数,紧跟在后面的模板字符串就是它的参数。
10.字符串的新增方法
(1)String.fromCharCode()
ES5提供String.fromCharCode()方法,用于返回Unicode码点返回对应字符,但是这个方法不能识别码点大于0xFFFF的字符。
(2)String.fromCodePoint()
ES6提供了String.fromCodePoint()方法,可以识别0xFFFF的字符,在作用上与codePointAt()方法相反。
(3)String.raw()
ES6 还为原生的 String 对象,提供了一个raw()方法。该方法返回一个斜杠都被转义(即斜杠前面再加一个斜杠)的字符串,往往用于模板字符串的处理方法。

String.raw`Hi\n${2+3}!`
// 实际返回 "Hi\\n5!",显示的是转义后的结果 "Hi\n5!"
String.raw`Hi\u000A!`;
// 实际返回 "Hi\\u000A!",显示的是转义后的结果 "Hi\u000A!"

String.raw()本质上是一个正常的函数,只是专用于模板字符串的标签函数。如果写成正常函数的形式,它的第一个参数,应该是一个具有raw属性的对象,且raw属性的值应该是一个数组,对应模板字符串解析后的值。

// `foo${1 + 2}bar`// 等同于
String.raw({ raw: ['foo', 'bar'] }, 1 + 2) // "foo3bar"

(4)codePointAt()
ES6提供了codePointAt()方法,能够正确处理4个字节储存的字符串,返回一个字符串的码点。
codePointAt()方法会正确返回 32 位的 UTF-16 字符的码点。对于那些两个字节储存的常规字符,它的返回结果与charCodeAt()方法相同。
codePointAt()方法返回的是码点的十进制值,如果想要十六进制的值,可以使用toString()方法转换一下。
(5)normalize()
ES6 提供字符串实例的normalize()方法,用来将字符的不同表示方法统一为同样的形式,这称为 Unicode 正规化。

'\u01D1'.normalize() === '\u004F\u030C'.normalize()
// true

normalize方法可以接受一个参数来指定normalize的方式,参数的四个可选值如下。
NFC,默认参数,表示“标准等价合成”(Normalization Form Canonical Composition),返回多个简单字符的合成字符。所谓“标准等价”指的是视觉和语义上的等价。
NFD,表示“标准等价分解”(Normalization Form Canonical Decomposition),即在标准等价的前提下,返回合成字符分解的多个简单字符。
NFKC,表示“兼容等价合成”(Normalization Form Compatibility Composition),返回合成字符。所谓“兼容等价”指的是语义上存在等价,但视觉上不等价,比如“囍”和“喜喜”。(这只是用来举例,normalize方法不能识别中文。)
NFKD,表示“兼容等价分解”(Normalization Form Compatibility Decomposition),即在兼容等价的前提下,返回合成字符分解的多个简单字符。

'\u004F\u030C'.normalize('NFC').length// 1
'\u004F\u030C'.normalize('NFD').length // 2

(6)includes(),startsWith(),endsWith()
JavaScript只有indexOf方法,可以用来确定一个字符是否包含在另一个字符串中。
includes():返回布尔值,表示是否找到参数字符串。
startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
endsWith(): 返回布尔值,表示参数字符串是否在原字符串的尾部。
使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。
(7)repeat()
Repeat方法返回一个新字符串,表示将原字符串重复n次。
(8)padStart(),padEnd()
ES2017 引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。
padStart()的常见用途是为数值补全指定位数。

'1'.padStart(10, '0') // "0000000001"
'12'.padStart(10, '0') // "0000000012"
'123456'.padStart(10, '0') // "0000123456"

另一个用途是提示字符串格式。

'12'.padStart(10, 'YYYY-MM-DD') //"YYYY-MM-12"
'09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"

(9)trimStart(),trimEnd()
trimStart()消除字符串头部的空格,trimEnd()消除尾部的空格。它们返回的都是新字符串,不会修改原始字符串。

const s = '  abc  ';
s.trim() // "abc"
s.trimStart() // "abc  "
s.trimEnd() // "  abc"

(10)matchAll()
matchAll()方法返回一个正则表达式在当前字符串的所有匹配。
11.正则的扩展
(1)RegExp构造函数
第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag)。

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

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

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

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

new RegExp(/abc/ig, 'i').flags
// "i"

(2)字符串的正则方法
字符串对象共有4个方法,可以使用正则表达式:match(),replace(),search(),split().
ES6 将这 4 个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上。
-String.prototype.match调用RegExp.prototype[Symbol.matxh]
-String.prototype.replace调用RegExp.prototype[Symbol.replace]
-String.prototype.search调用RegExp.prototype[Symbol.search]
-String.prototype.split调用RegExp.prototype[Symbol.split]
(3)u修饰符
ES6 对正则表达式添加了u修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。也就是说,会正确处理四个字节的 UTF-16 编码。
一旦加上u修饰符号,就会修改下面这些正则表达式的行为。
1)点字符
点(.)字符在正则表达式中,含义是除了换行符以外的任意单个字符。对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上u修饰符。

var s = ';
/^.$/.test(s) // false
/^.$/u.test(s) // true

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

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

3)量词
使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的Unicode字符。
4)预定义模式
u修饰符也影响到预定义模式,能否正确识别码点大于0xFFFF的 Unicode 字符。

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

\S是预定义模式,匹配所有非空白字符
5)i修饰符
有些 Unicode 字符的编码不同,但是字型很相近,比如,\u004B与\u212A都是大写的K。
6)转义
没有u修饰符的情况下,正则中没有定义的转义(如逗号的转义,)无效,而在u模式会报错。
(4)RegExp.prototype.incode属性
正则实例对象新增unicode属性,表示是否设置了u修饰符。
(5)y修饰符
除了u修饰符,ES6 还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。
y修饰符的作用与g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。
(6)RegExp.prototype.sticky属性
表示是否设置了y修饰符。
(7)RegExp.prototype.flags属性
ES6 为正则表达式新增了flags属性,会返回正则表达式的修饰符。

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

(8)s修饰符:dotAll模式
正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符。
所谓行终止符,就是该字符表示一行的终结。以下四个字符属于“行终止符”。
U+000A 换行符(\n)
U+000D 回车符(\r)
U+2028 行分隔符(line separator)
U+2029 段分隔符(paragraph separator)
匹配的是任意单个字符

/foo[^]bar/.test('foo\nbar')
// true

ES2018 引入s修饰符,使得.可以匹配任意单个字符。

/foo.bar/s.test('foo\nbar') // true

这被称为dotAll模式,即点(dot)代表一切字符。所以,正则表达式还引入了一个dotAll属性,返回一个布尔值,表示该正则表达式是否处在dotAll模式。
/s修饰符和多行修饰符/m不冲突,两者一起使用的情况下,.匹配所有字符,而^和$匹配每一行的行首和行尾。
(8)先行断言
“先行断言”指的是,x只有在y前面才匹配,必须写成/x(?=y)/。比如,只匹配百分号之前的数字,要写成/\d+(?=%)/。“先行否定断言”指的是,x只有不在y前面才匹配,必须写成/x(?!y)/。比如,只匹配不在百分号之前的数字,要写成/\d+(?!%)/。
(9)后行断言
“后行断言”正好与“先行断言”相反,x只有在y后面才匹配,必须写成/(?<=y)x/。“后行否定断言”则与“先行否定断言”相反,x只有不在y后面才匹配,必须写成/(?<!y)x/。比如,只匹配不在美元符号后面的数字,要写成/(?<!$)\d+/。
(10)Unicode属性类
ES2018 引入了一种新的类的写法\p{…}和\P{…},允许正则表达式匹配符合 Unicode 某种属性的所有字符。
\P{…}是\p{…}的反向匹配,即匹配不满足条件的字符。
\p{Script=Greek}指定匹配一个希腊文字母,所以匹配π成功
Unicode 属性类要指定属性名和属性值。

\p{UnicodePropertyName=UnicodePropertyValue}

\p{Decimal_Number} 属性类指定匹配所有十进制字符。
\p{Number}甚至能匹配罗马数字。
\p{White_Space} // 匹配所有空格

// 匹配各种文字的所有字母,等同于 Unicode 版的\w
[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]
// 匹配各种文字的所有非字母的字符,等同于 Unicode 版的 \W
[^\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\p{Join_Control}]
// 匹配 Emoji
/\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu
// 匹配所有的箭头字符
const regexArrows = /^\p{Block=Arrows}+$/u;
regexArrows.test('←↑→↓↔↕↖↗↘↙⇏⇐⇑⇒⇓⇔⇕⇖⇗⇘⇙⇧⇩') // true

(11)具名组匹配
正则表达式使用圆括号进行匹配。
const RE_DATE= /(\d{4})-(\d{2})-(\d{2})/;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值