ECMAScript - Introducing String "matchAll" Method in ES2020 (ES11)

栏目: IT技术 · 发布时间: 4年前

内容简介:Every year, an edition of the ECMAScript Language Specification is released with the new proposals that are officially ready. In practical terms, the proposals are attached to the latest expected edition when they are accepted and reachedIn this article, w

Every year, an edition of the ECMAScript Language Specification is released with the new proposals that are officially ready. In practical terms, the proposals are attached to the latest expected edition when they are accepted and reached stage 4 in the TC39 process:

ECMAScript - Introducing String

The stages of TC39 process

In this article, we’re going to examine and explain the “String.prototype.matchAll” proposal that has been reached stage 4 and belongs to ECMAScript 2020 - the 11th edition.

Motivation

Capturing groups in regular expressions are multiple characters that are enclosed within parentheses and treated as a single unit. This means that setting a quantifier at the end of the parentheses allows referring to the entire grouped characters (and not just the single leading character).

When involving the String.prototype.match method against a regular expression containing capturing groups, the result is typically an array (would be null if no matches are found) that might be produced with different content - depending on whether we use the g flag or not.

Let’s demonstrate the difference between the results.

All Matches without Capturing Groups

To begin with, we execute the method against a global regular expression that’s built from multiple groups:

As it stands, the result doesn’t contain the matching capturing groups at all - but rather the entire set of characters that are matched. For instance, “e” and “st1” are strings matching the capturing groups - so we would expect them to be contained as well.

That is, the capturing groups are ignored . ‍♂️

The First Match with Capturing Groups

This time we execute against the same regex without using the g flag:

Well, the multiple capturing groups indeed considered in the result - but it refers only to the first match. ‍♂️

Notice that the result isn’t just an array of plain strings - it actually has additional properties: index , input and groups . Later, we’ll name these objects “matching values”.

Having said that, what if we’d like to combine both use-cases above so that:

  • We retrieve results for all matches considering the capturing groups
  • We retrieve them simply without getting complicated

How do we make it?

The Proposal

The proposal specifies a new String.prototype.matchAll method that addresses the case in question.

Here’s the official definition out of the specification:

Performs a regular expression match of the String representing the this value against regexp and returns an iterator. Each iteration result’s value is an Array object containing the results of the match, or null if the String did not match.

We can understand from the definition that:

  • The method returns an iterator representing results of the matches
  • The method returns null if there are no matches
  • All results of each match are contained

Put it simply, the results of each match (namely “matching values”) truly consider capturing groups and are accessible through the returned iterator.

Next, we’re going to introduce several practical usages for the method.

All Matches with Capturing Groups

Starting with executing the String.prototype.matchAll method against our regex:

The method merely takes a regex, like String.prototype.match does, but differs in the result type. Importantly, only global regular expressions are acceptable - which means, we must use the g flag to avoid getting a TypeError .

Here we explore the result:

Since we already know that the result is an iterator, we spread it into resultAsArray to easily access the matching values.

The first matching value is absolutely identical to the result in the case of String.prototype.match without the g flag. The cool thing, however, is having an additional matching value - which refers to the second match and also considers its capturing groups!

Thereby, instead of messing with complicated solutions to combine the global matching results with capturing groups - the method provides this combination simply and natively. :muscle|type_1_2:

Iterating the Matches

So far, the common practice to iterate all the matching values was using a while loop:

Now with String.prototype.matchAll , we can benefit from the returned iterator to implement conveniently:

The output obviously remains the same.

Also, we can destructure the iterator to access a specific matching value:

It’s worth mentioning that both practices above exhaust the iterator (we reached the last value) - meaning, we need to have another non-consumed iterator by reinvoking the method in order to iterate or destructure (which actually iterates indirectly) again.

Hence, another way to go is by creating an array to be iterated repeatedly:

Thus it’s possible to iterate the matching values as we please without reinvoking the method.

The truth is that in the majority of cases we could settle for an iterator, and that’s the primary reason behind the design decision to always return an iterator instead of an array. Other than that, there is a matter of performance - the iterator performs the matching for each invocation of its next method. Practically this means that if we decide to break the loop in the middle or destructure only part of the values, the next matches wouldn’t be performed. By contrast, if the result was an array - all the matching values would be collected beforehand without exception. It’s definitely significant when there are tons of potential matches and/or capturing groups.

Anyway, on the whole, the point is we’re not restricted. The iterator provides the versatility to iterate, destructure or transform by choice to an array - depending on our use-case.

Summary

We explained today the primary reason motivating the “String.prototype.matchAll” proposal and also introduced concrete usages to the method.

Let’s recap:

  • The proposal belongs to ECMAScript 2020, which is the 11th edition
  • When using String.prototype.match with g flag, the result doesn’t consider capturing groups
  • When using String.prototype.match without g flag, the result considers the capturing groups but refers only to the first match
  • The proposal specifies new method called String.prototype.matchAll
  • String.prototype.matchAll returns an iterator representing the matches and allowing to iterate, destructure or transform to an array if necessary
  • String.prototype.matchAll returns null if there are no matches
  • String.prototype.matchAll considers all matches including capturing groups in a simple usage
  • String.prototype.matchAll throws a TypeError when using non-global regular expression
  • After exhausting the iterator, we need to reinvoke String.prototype.matchAll to iterate once more

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web 2.0界面设计模式

Web 2.0界面设计模式

黄玮 / 电子工业出版社 / 2013-9-1 / 59

本书集Web 2.0的发展及特点、Web 2.0界面设计模式基本理论、实际模式实践及代码实现等诸多内容于一身,具有很强的实用性。这些内容不是简单的顺序堆砌,而是以Web 2.0界面设计模式和应用为主线,其中完美地穿插了各种与之相关的Web 2.0设计理念、用户行为模式、用户体验及基于Dojo的实现方式等相关知识,真正做到将Web 2.0界面设计模式所需要的方方面面的知识有机地融为一个整体。实现不需......一起来看看 《Web 2.0界面设计模式》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换