11# 捕获组
22
3- 模式的一部分可以用括号括起来 ` pattern:(...) ` 。这称为 “捕获组(capturing group)”。
3+ 模式的一部分可以用括号括起来 ` pattern:(...) ` 。这被称为 “捕获组(capturing group)”。
44
55这有两个影响:
66
@@ -43,15 +43,15 @@ let regexp = /(\w+\.)+\w+/g;
4343alert ( " site.com my.site.com" .match (regexp) ); // site.com,my.site.com
4444```
4545
46- 搜索有效,但是该模式无法匹配带有连字符的域名 ,例如 my-site.com,因为连字符不属于 ` pattern:\w ` 类。
46+ 搜索有效,但该模式无法匹配带有连字符的域名 ,例如 my-site.com,因为连字符不属于 ` pattern:\w ` 类。
4747
48- 我们可以通过用 ` pattern:[\w-] ` 替换 ` pattern:\w ` 来匹配除最后一个的每个单词 :` pattern:([\w-]+\.)+\w+ ` 。
48+ 我们可以通过用 ` pattern:[\w-] ` 替换 ` pattern:\w ` 来匹配除最后一个单词以外的每个单词 :` pattern:([\w-]+\.)+\w+ ` 。
4949
50- ### 示例:email
50+ ### 示例:电子邮件
5151
52- 前面的示例可以扩展 。我们可以基于它为电子邮件创建一个正则表达式。
52+ 扩展一下上面这个示例 。我们可以基于它为电子邮件创建一个正则表达式。
5353
54- email 格式为 :` name@domain ` 。名称可以是任何单词,可以使用连字符和点 。在正则表达式中为 ` pattern:[-.\w]+ ` 。
54+ 电子邮件的格式为 :` name@domain ` 。名称可以是任何单词,允许使用连字符和点 。在正则表达式中为 ` pattern:[-.\w]+ ` 。
5555
5656模式:
5757
@@ -61,24 +61,24 @@ let regexp = /[-.\w]+@([\w-]+\.)+[\w-]+/g;
6161alert (" my@mail.com @ his@site.com.uk" .match (regexp)); // my@mail.com, his@site.com.uk
6262```
6363
64- 该正则表达式并不完美的,但多数情况下都可以工作,并且有助于修复意外的错误类型。唯一真正可靠的 email 检查只能通过发送 email 来完成 。
64+ 该正则表达式并不完美的,但多数情况下都能正确匹配,并且有助于修复输入邮箱时的意外错误输入。唯一真正可靠的电子邮件检查只能通过发送电子邮件来完成 。
6565
66- ## 匹配括号中的内容
66+ ## 匹配中的括号的内容
6767
68- 括号从左到右编号 。正则引擎会记住它们各自匹配的内容,并允许在结果中获得它 。
68+ 括号被从左到右编号 。正则引擎会记住它们各自匹配的内容,并允许在结果中获取它 。
6969
70- 方法 ` str.match(regexp) ` ,如果 ` regexp ` 没有 ` g ` 标志,将查找第一个匹配并将它作为一个数组返回 :
70+ 方法 ` str.match(regexp) ` ,如果 ` regexp ` 没有修饰符 ` g ` ,将查找第一个匹配项,并将它作为数组返回 :
7171
72- 1 . 在索引 ` 0 ` 处:完全匹配 。
72+ 1 . 在索引 ` 0 ` 处:完整的匹配项 。
73732 . 在索引 ` 1 ` 处:第一个括号的内容。
74743 . 在索引 ` 2 ` 处:第二个括号的内容。
75- 4 . …等等 …
75+ 4 . ……等等… …
7676
77- 例如,我们想找到 HTML 标记 ` pattern:<.*?> ` 并进行处理。这将很方便的把标签内容 (尖括号内的内容)放在单独的变量中 。
77+ 例如,我们想找到 HTML 标签 ` pattern:<.*?> ` 并处理它们。将标签内容 (尖括号内的内容)放在单独的变量中会很方便 。
7878
7979让我们将内部内容包装在括号中,像这样:` pattern:<(.*?)> ` 。
8080
81- 现在,我们能在结果数组中获取标签的整体 ` match:<h1> ` 及其内容 ` match:h1 ` :
81+ 现在,我们在结果数组中得到了标签的整体 ` match:<h1> ` 及其内容 ` match:h1 ` :
8282
8383``` js run
8484let str = ' <h1>Hello, world!</h1>' ;
@@ -93,19 +93,19 @@ alert( tag[1] ); // h1
9393
9494括号可以嵌套。在这种情况下,编号也从左到右。
9595
96- 例如,在搜索标签 ` subject:<span class="my"> ` 时我们可能会对以下内容感兴趣 :
96+ 例如,在搜索标签 ` subject:<span class="my"> ` 时,我们可能会对以下内容感兴趣 :
9797
98- 1 . 整个标签内容 :` match:span class="my" ` 。
98+ 1 . 整个标签的内容 :` match:span class="my" ` 。
99992 . 标签名称:` match:span ` 。
100- 3 . 标签属性 :` match:class="my" ` 。
100+ 3 . 标签特性 :` match:class="my" ` 。
101101
102102让我们为它们添加括号:` pattern:<(([a-z]+)\s*([^>]*))> ` 。
103103
104- 这是它们的编号方式(从左到右,由左括号开始 ):
104+ 这是它们的编号方式(根据左括号从左到右 ):
105105
106106![ ] ( regexp-nested-groups-pattern.svg )
107107
108- 实际上 :
108+ 验证 :
109109
110110``` js run
111111let str = ' <span class="my">' ;
@@ -119,57 +119,57 @@ alert(result[2]); // span
119119alert (result[3 ]); // class="my"
120120```
121121
122- ` result ` 的零索引始终保持完全匹配 。
122+ ` result ` 的索引 0 中始终保存的是正则表达式的完整匹配项 。
123123
124- 然后按左括号将组从左到右编号 。第一组返回为 ` result[1] ` 。它包含了整个标签内容。
124+ 然后是按左括号从左到右编号的组 。第一组返回为 ` result[1] ` 。它包含了整个标签内容。
125125
126- 然后 ` result[2] ` 从第二个开始的括号中进入该组 ` pattern:([a-z]+) ` —— 标签名称,然后在 ` result[3] ` 标签中 :` pattern:([^>]*) ` 。
126+ 然后是 ` result[2] ` ,从第二个左括号开始分组 ` pattern:([a-z]+) ` —— 标签名称,然后在 ` result[3] ` 中 :` pattern:([^>]*) ` 。
127127
128128字符串中每个组的内容:
129129
130130![ ] ( regexp-nested-groups-matches.svg )
131131
132132### 可选组
133133
134- 即使组是可选的并且在匹配项中不存在(例如,具有数量词 ` pattern:(...)? ` ),也存在相应的 ` result ` 数组项,并且等于 ` undefined ` 。
134+ 即使组是可选的并且在匹配项中不存在(例如,具有量词 ` pattern:(...)? ` ),也存在相应的 ` result ` 数组项,并且等于 ` undefined ` 。
135135
136- 例如,让我们考虑正则 ` pattern:a(z)?(c)? ` 。它寻找 ` "a" ` ,然后是可选的 ` "z" ` ,然后是可选的 ` "c" ` 。
136+ 例如,让我们考虑正则表达式 ` pattern:a(z)?(c)? ` 。它查找 ` "a" ` ,后面是可选的 ` "z" ` ,然后是可选的 ` "c" ` 。
137137
138138如果我们在单个字母的字符串上运行 ` subject:a ` ,则结果为:
139139
140140``` js run
141141let match = ' a' .match (/ a(z)? (c)? / );
142142
143143alert ( match .length ); // 3
144- alert ( match[0 ] ); // a(完全匹配 )
144+ alert ( match[0 ] ); // a(完整的匹配项 )
145145alert ( match[1 ] ); // undefined
146146alert ( match[2 ] ); // undefined
147147```
148148
149149数组的长度为 ` 3 ` ,但所有组均为空。
150150
151- 这是字符串的一个更复杂的匹配 ` subject:ac ` :
151+ 对字符串 ` subject:ac ` 的匹配会更复杂 :
152152
153153``` js run
154154let match = ' ac' .match (/ a(z)? (c)? / )
155155
156156alert ( match .length ); // 3
157- alert ( match[0 ] ); // ac(完全匹配 )
158- alert ( match[1 ] ); // undefined,因为 (z)? 没匹配项
157+ alert ( match[0 ] ); // ac(完整的匹配项 )
158+ alert ( match[1 ] ); // undefined, 因为没有 (z)? 的匹配项
159159alert ( match[2 ] ); // c
160160```
161161
162- 数组长度是恒定的 :` 3 ` 。但是对于组 ` pattern:(z)? ` 而言,什么都没有 ,所以结果是 ` ["ac", undefined, "c"] ` 。
162+ 数组长度依然是 :` 3 ` 。但没有组 ` pattern:(z)? ` 的匹配项 ,所以结果是 ` ["ac", undefined, "c"] ` 。
163163
164- ## 搜索所有具有组的匹配项 :matchAll
164+ ## 带有组搜索所有匹配项 :matchAll
165165
166166```warn header="` matchAll ` 是一个新方法,可能需要使用 polyfill"
167167旧的浏览器不支持 ` matchAll ` 。
168168
169- 可能需要一个 polyfill,例如 < https://github.com/ljharb/String.prototype.matchAll > .
169+ 可能需要进行 polyfill,例如 < https://github.com/ljharb/String.prototype.matchAll > .
170170```
171171
172- 当我们搜索所有匹配项(标志 `pattern:g`)时,`match` 方法不会返回组的内容。
172+ 当我们搜索所有匹配项(修饰符 `pattern:g`)时,`match` 方法不会返回组的内容。
173173
174174例如,让我们查找字符串中的所有标签:
175175
@@ -185,31 +185,31 @@ alert( tags ); // <h1>,<h2>
185185
186186要获取它们,我们应该使用方法 ` str.matchAll(regexp) ` 进行搜索。
187187
188- 在使用 ` match ` 很长一段时间后,它作为 “新的改进版本”被加入到 JavaScript 中。
188+ 在使用 ` match ` 很长一段时间后,它才被作为 “新的改进版本”被加入到 JavaScript 中。
189189
190190就像 ` match ` 一样,它寻找匹配项,但有 3 个区别:
191191
1921921 . 它返回的不是数组,而是一个可迭代的对象。
193- 2 . 当标志 ` pattern:g ` 存在时,它将每个匹配组作为一个数组返回 。
194- 3 . 如果没有匹配项,则不返回 ` null ` ,而是返回一个空的可迭代对象 。
193+ 2 . 当存在修饰符 ` pattern:g ` 时,它将每个匹配项以包含组的数组的形式返回 。
194+ 3 . 如果没有匹配项,则返回的不是 ` null ` ,而是一个空的可迭代对象 。
195195
196196例如:
197197
198198``` js run
199199let results = ' <h1> <h2>' .matchAll (/ <(. *? )>/ gi );
200200
201- // results - is not an array, but an iterable object
201+ // results —— 不是数组,而是一个迭代对象
202202alert (results); // [object RegExp String Iterator]
203203
204204alert (results[0 ]); // undefined (*)
205205
206- results = Array .from (results); // let's turn it into array
206+ results = Array .from (results); // 让我们将其转换为数组
207207
208- alert (results[0 ]); // <h1>,h1 (1st tag)
209- alert (results[1 ]); // <h2>,h2 (2nd tag)
208+ alert (results[0 ]); // <h1>,h1(第一个标签)
209+ alert (results[1 ]); // <h2>,h2(第二个标签)
210210```
211211
212- 我们可以看到,第一个区别非常重要,如 ` (*) ` 行所示。我们无法获得 ` results[0] ` 的匹配内容 ,因为该对象是伪数组。我们可以使用 ` Array.from ` 把它变成一个真正的 ` Array ` 。在 Iterable(可迭代对象) < info:iterable > 一文中有关于伪数组和可迭代对象的更多详细信息 。
212+ 我们可以看到,第一个区别非常重要,如 ` (*) ` 行所示。我们无法获得 ` results[0] ` 的匹配项 ,因为该对象是伪数组。我们可以使用 ` Array.from ` 把它变成一个真正的 ` Array ` 。在 < info:iterable > 一文中有关于伪数组和可迭代对象的更多详细内容 。
213213
214214如果我们不需要遍历结果,则 ` Array.from ` 没有必要:
215215
@@ -218,8 +218,8 @@ let results = '<h1> <h2>'.matchAll(/<(.*?)>/gi);
218218
219219for (let result of results) {
220220 alert (result);
221- // 第一个结果: <h1>,h1
222- // 第二个结果: <h2>,h2
221+ // 第一个 alert: <h1>,h1
222+ // 第二个: <h2>,h2
223223}
224224```
225225
@@ -229,7 +229,7 @@ for(let result of results) {
229229let [tag1, tag2] = ' <h1> <h2>' .matchAll (/ <(. *? )>/ gi );
230230```
231231
232- 由 ` matchAll ` 所返回的每个匹配,其格式与不带标志 ` pattern:g ` 的 ` match ` 所返回的格式相同:它是一个具有额外的 ` index ` (字符串中的匹配索引)属性和 ` input ` (源字符串)的数组:
232+ ` matchAll ` 返回的每个匹配项,与不带修饰符 ` pattern:g ` 的 ` match ` 所返回的格式相同:具有额外 ` index ` (字符串中的匹配索引)属性和 ` input ` (源字符串)的数组:
233233
234234``` js run
235235let results = ' <h1> <h2>' .matchAll (/ <(. *? )>/ gi );
@@ -243,20 +243,20 @@ alert( tag1.input ); // <h1> <h2>
243243```
244244
245245```smart header="为什么 ` matchAll ` 的结果是可迭代对象而不是数组?"
246- 为什么这个方法这样设计?原因很简单 — 为了优化。
246+ 为什么这个方法这样设计?原因很简单 —— 为了优化。
247247
248- 调用 ` matchAll ` 不会执行搜索。相反,它返回一个可迭代的对象 ,最初没有结果。每当我们对它进行迭代时才会执行搜索 ,例如在循环中。
248+ 调用 ` matchAll ` 不会执行搜索。相反,它返回一个可迭代对象 ,最初没有结果。每次我们迭代它时才会执行搜索 ,例如在循环中。
249249
250- 因此,这将根据需要找到尽可能多的结果 ,而不是全部。
250+ 因此,这将根据需要找出尽可能多的结果 ,而不是全部。
251251
252- 例如,文本中可能有 100 个匹配项,但是在一个 ` for..of ` 循环中,我们已经找到了 5 个匹配项,然后觉得足够了并做出一个 ` break ` 。这时引擎就不会花时间查找其他 95 个匹配。
252+ 例如,文本中可能有 100 个匹配项,但在一个 ` for..of ` 循环中,我们找到了 5 个匹配项,然后觉得足够了并做出一个 ` break ` 。这时引擎就不会花时间查找其他 95 个匹配。
253253```
254254
255255## 命名组
256256
257- 用数字记录组很困难。对于简单模式 ,它是可行的,但对于更复杂的模式,计算括号很不方便。我们有一个更好的选择:给括号起个名字 。
257+ 用数字记录组很困难。对于简单的模式 ,它是可行的,但对于更复杂的模式,计算括号很不方便。我们有一个更好的选择:给括号命名 。
258258
259- 这是通过在开始括号之后立即放置 `pattern:?<name>` 来完成的 。
259+ 在左括号后紧跟着放置 `pattern:?<name>` 即可完成对括号的命名 。
260260
261261例如,让我们查找 "year-month-day" 格式的日期:
262262
@@ -273,11 +273,11 @@ alert(groups.month); // 04
273273alert(groups.day); // 30
274274```
275275
276- 如您所见 ,匹配的组在 ` .groups ` 属性中。
276+ 正如你所看到的 ,匹配的组在 ` .groups ` 属性中。
277277
278- 要查找所有日期,我们可以添加标志 ` pattern:g ` 。
278+ 要查找所有日期,我们可以添加修饰符 ` pattern:g ` 。
279279
280- 我们还需要 ` matchAll ` 获取完整的组匹配 :
280+ 我们还需要 ` matchAll ` 以获取完整的组匹配 :
281281
282282``` js run
283283let dateRegexp = / (?<year>[0-9 ] {4} )-(?<month>[0-9 ] {2} )-(?<day>[0-9 ] {2} )/ g ;
@@ -295,9 +295,9 @@ for(let result of results) {
295295}
296296```
297297
298- ## 替换捕获组
298+ ## 替换中的捕获组
299299
300- 方法 ` str.replace(regexp, replacement) ` 用 ` replacement ` 替换 ` str ` 中匹配 ` regexp ` 的所有捕获组 。这使用 ` pattern:$n ` 来完成,其中 ` pattern:n ` 是组号。
300+ 让我们能够替换 ` str ` 中 ` regexp ` 的所有匹配项的方法 ` str .replace(regexp, replacement)` 允许我们在 ` replacement ` 字符串中使用括号中的内容 。这使用 ` pattern:$n ` 来完成,其中 ` pattern:n ` 是组号。
301301
302302例如,
303303
@@ -308,7 +308,7 @@ let regexp = /(\w+) (\w+)/;
308308alert ( str .replace (regexp, ' $2, $1' ) ); // Bull, John
309309```
310310
311- 对于命名括号 ,引用为 ` pattern:$<name> ` 。
311+ 对于命名的括号 ,引用为 ` pattern:$<name> ` 。
312312
313313例如,让我们将日期格式从 "year-month-day" 更改为 "day.month.year":
314314
@@ -323,7 +323,7 @@ alert( str.replace(regexp, '$<day>.$<month>.$<year>') );
323323
324324## 非捕获组 ?:
325325
326- 有时我们需要括号才能正确应用量词 ,但我们不希望它们的内容出现在结果中。
326+ 有时我们需要用括号才能正确应用量词 ,但我们不希望它们的内容出现在结果中。
327327
328328可以通过在开头添加 ` pattern:?: ` 来排除组。
329329
@@ -341,24 +341,24 @@ let regexp = /(?:go)+ (\w+)/i;
341341
342342let result = str .match (regexp);
343343
344- alert ( result[0 ] ); // Gogogo John(完全匹配 )
344+ alert ( result[0 ] ); // Gogogo John(完整的匹配项 )
345345alert ( result[1 ] ); // John
346- alert ( result .length ); // 2(数组中没有更多项 )
346+ alert ( result .length ); // 2(在数组中没有其他数组项 )
347347```
348348
349349## 总结
350350
351- 括号将正则表达式的一部分组合在一起 ,以便量词可以整体应用。
351+ 括号将正则表达式中的一部分组合在一起 ,以便量词可以整体应用。
352352
353353括号组从左到右编号,可以选择用 ` (?<name>...) ` 命名。
354354
355355可以在结果中获得按组匹配的内容:
356356
357- * 方法 ` str.match ` 仅当不带标志 ` pattern:g ` 时返回捕获组。
357+ * 方法 ` str.match ` 仅当不带修饰符 ` pattern:g ` 时返回捕获组。
358358* 方法 ` str.matchAll ` 始终返回捕获组。
359359
360360如果括号没有名称,则匹配数组按编号提供其内容。命名括号还可使用属性 ` groups ` 。
361361
362- 我们还可以使用 ` str.replace ` 来替换括号内容中的字符串:使用 ` $n ` 或者名称 ` $<name> ` 。
362+ 我们还可以在 ` str.replace ` 的替换字符串中使用括号内容:通过数字 ` $n ` 或者=名称 ` $<name> ` 。
363363
364- 可以通过在组的开头添加 ` pattern:?: ` 来排除编号组 。当我们需要对整个组应用量词,但不希望将其作为结果数组中的单独项时这很有用。我们也不能在替换字符串时引用此类括号 。
364+ 可以通过在组的开头添加 ` pattern:?: ` 来排除编号 。当我们需要对整个组应用量词,但不希望将其作为结果数组中的单独项时这很有用。我们也不能在替换字符串中引用这样的括号 。
0 commit comments