11# 集合和范围 [ ...]
22
3- 在方括号 ` […] ` 中的几个字符或者字符类意味着“搜索给定的字符中的任意一个 ”。
3+ 在方括号 ` […] ` 中的几个字符或者字符类表示“搜索给定字符中的任意一个 ”。
44
55## 集合
66
7- 比如说 ,` pattern:[eao] ` 意味着查找在 3 个字符 ` 'a' ` 、` 'e' ` 或者 `'o' 中的任意一个 。
7+ 例如 ,` pattern:[eao] ` 表示以下 3 个字符中的任何一个: ` 'a' ` 、` 'e' ` 或 ` 'o' ` 。
88
9- 这被叫做一个 ** 集合** 。集合可以在正则表达式中和其它常规字符一起使用 。
9+ 这就是所谓的 ** 集合** 。在正则表达式中,可以将集合和常规字符一起使用 。
1010
1111``` js run
12- // 查找 [t 或者 m],然后再匹配 “op”
12+ // 查找 [t 或 m],然后匹配 "op"
1313alert ( " Mop top" .match (/ [tm] op/ gi ) ); // "Mop", "top"
1414```
1515
16- 请注意尽管在集合中有多个字符 ,但它们在匹配中只会对应其中的一个。
16+ 请注意,虽然集合中有多个字符 ,但它们在匹配中只会对应其中的一个。
1717
18- 所以下面的示例并不会匹配上 :
18+ 所以在下面的示例中并没有匹配项 :
1919
2020``` js run
21- // 查找 “V” ,然后匹配 [o 或者 i],之后再匹配 “la”
22- alert ( " Voila" .match (/ V[oi] la/ ) ); // null,并没有匹配上
21+ // 查找 "V" ,然后匹配 [o 或 i],之后匹配 "la"
22+ alert ( " Voila" .match (/ V[oi] la/ ) ); // null,无匹配项
2323```
2424
25- 这个模式会做以下假设 :
25+ 这个模式会搜索 :
2626
2727- ` pattern:V ` ,
28- - 然后匹配其中的** 一个字符** ` pattern:[oi] ` ,
29- - 然后匹配 ` pattern:la ` ,
28+ - 然后匹配其中的 ** 一个字符** ` pattern:[oi] ` ,
29+ - 然后匹配 ` pattern:la ` 。
3030
3131所以可以匹配上 ` match:Vola ` 或者 ` match:Vila ` 。
3232
3333## 范围
3434
35- 方括号也可以包含** 字符范围** 。
35+ 方括号也可以包含 ** 字符范围** 。
3636
37- 比如说 ,` pattern:[a-z] ` 会匹配从 ` a ` 到 ` z ` 范围内的字母 ,` pattern:[0-5] ` 表示从 ` 0 ` 到 ` 5 ` 的数字。
37+ 例如 ,` pattern:[a-z] ` 表示从 ` a ` 到 ` z ` 范围内的字符 ,` pattern:[0-5] ` 表示从 ` 0 ` 到 ` 5 ` 的数字。
3838
39- 在下面的示例中,我们会查询首先匹配 ` "x" ` 字符,再匹配两个数字或者位于 ` A ` 到 ` F ` 范围内的字符 。
39+ 在下面的示例中,我们将搜索首先是 ` "x" ` ,然后有两位数或两个在 ` A ` 到 ` F ` 范围内的字符紧随其后的字符串 。
4040
4141``` js run
4242alert ( " Exception 0xAF" .match (/ x[0-9A-F ][0-9A-F ] / g ) ); // xAF
4343```
4444
45- ` pattern:[0-9A-F] ` 表示两个范围 :它搜索一个字符,满足数字 ` 0 ` 到 ` 9 ` 或字母 ` A ` 到 ` F ` 。
45+ ` pattern:[0-9A-F] ` 中有两个范围 :它搜索一个字符,该字符要么是在 ` 0 ` 到 ` 9 ` 范围内的数字,要么是从 ` A ` 到 ` F ` 的字母 。
4646
4747如果我们还想查找小写字母,则可以添加范围 ` a-f ` :` pattern:[0-9A-Fa-f] ` 。或添加标志 ` pattern:i ` 。
4848
49- 我们也可以在 ` […] ` 里面使用字符类 。
49+ 我们也可以在 ` […] ` 中使用字符类 。
5050
51- 例如,如果我们想要查找单词字符 ` pattern:\w ` 或连字符 ` pattern:- ` ,则该集合为 ` pattern:[\w-] ` 。
51+ 例如,如果我们想查找单词字符 ` pattern:\w ` 或连字符 ` pattern:- ` ,则集合可以写为 ` pattern:[\w-] ` 。
5252
53- 也可以组合多个类,例如 ` pattern:[\s\d] ` 表示 “空格字符或数字”。
53+ 也可以组合多个类,例如 ` pattern:[\s\d] ` 表示“空格字符或数字”。
5454
55- ``` smart header="字符类是某些字符集的简写 "
55+ ``` smart header="字符类是某些字符集合的简写 "
5656例如:
5757
5858* **\d** —— 和 `pattern:[0-9]` 相同,
5959* **\w** —— 和 `pattern:[a-zA-Z0-9_]` 相同,
60- * **\s** —— 和 `pattern:[\t\n\v\f\r ]` 外加少量罕见的 unicode 空格字符相同。
60+ * **\s** —— 和 `pattern:[\t\n\v\f\r ]` 外加少量罕见的 Unicode 空格字符相同。
6161```
6262
6363### 示例:多语言 \w
6464
6565由于字符类 ` pattern:\w ` 是简写的 ` pattern:[a-zA-Z0-9_] ` ,因此无法找到中文象形文字,西里尔字母等。
6666
67- 我们可以编写一个更通用的模式,该模式可以查找任何语言中的文字字符。这很容易想到就 Unicode 属性 :` pattern:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}] ` 。
67+ 我们可以编写一个更通用的模式,该模式可以查找任何语言中的单词字符。借助 Unicode 属性很容易实现 :` pattern:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}] ` 。
6868
69- 让我们理解它 。类似于 ` pattern:\w ` ,我们在制作自己的一套字符集,包括以下 unicode 字符 :
69+ 让我们理解一下 。类似于 ` pattern:\w ` ,我们正在制作一组属于我们自己的包含具有以下 Unicode 属性的字符 :
7070
7171* ` Alphabetic ` (` Alpha ` ) —— 字母,
72- * ` Mark ` (` M ` ) —— 重读 ,
72+ * ` Mark ` (` M ` ) —— 音调 ,
7373* ` Decimal_Number ` (` Nd ` ) —— 数字,
7474* ` Connector_Punctuation ` (` Pc ` ) —— 下划线 ` '_' ` 和类似的字符,
75- * ` Join_Control ` (` Join_C ` ) —— 两个特殊代码 ` 200c ` and ` 200d ` ,用于连字,例如阿拉伯语。
75+ * ` Join_Control ` (` Join_C ` ) —— 两个特殊代码 ` 200c ` 和 ` 200d ` ,用于连字,例如阿拉伯语。
7676
7777使用示例:
7878
@@ -81,119 +81,117 @@ let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;
8181
8282let str = ` Hi 你好 12` ;
8383
84- // finds all letters and digits:
84+ // 找出所有字母和数字:
8585alert ( str .match (regexp) ); // H,i,你,好,1,2
8686```
8787
88- 当然,我们可以编辑此模式 :添加 unicode 属性或删除它们。文章 < info:regexp-unicode > 中包含了更多 Unicode 属性的细节 。
88+ 当然,我们可以编辑这个模式 :添加 Unicode 属性或删除它们。< info:regexp-unicode > 一文更详细地介绍了 Unicode 属性 。
8989
90- ``` warn header="Edge 和 Firefox 不支持 Unicode 属性"
91- Edge 和 Firefox 尚未实现 Unicode 属性 `pattern:p{… }`。如果确实需要它们 ,可以使用库 [XRegExp](http://xregexp.com/)。
90+ ``` warn header="IE 浏览器不支持 Unicode 属性"
91+ IE 浏览器未实现 Unicode 属性 `pattern:p{... }`。如果我们真的需要它们 ,可以使用库 [XRegExp](http://xregexp.com/)。
9292
93- 或者只使用我们想要的语言范围的字符,例如西里尔字母 `pattern:[а-я]`。
93+ 或者只是使用我们感兴趣的语言中的字符范围,例如西里尔字母范围 `pattern:[а-я]`。
9494```
9595
9696## 排除范围
9797
98- 除了普通的范围匹配,还有类似 ` pattern:[^…] ` 的“排除”范围匹配。
98+ 除了普通的范围匹配,还有像这样 ` pattern:[^…] ` 的“排除”范围匹配。
9999
100- 它们通过在匹配查询的开头添加插入符号 ` ^ ` 来表示,它会匹配所有 ** 除了给定的字符** 之外的任意字符。
100+ 通过在开头添加插入符号 ` ^ ` 来表示匹配所有 ** 除了给定的字符** 之外的任意字符。
101101
102- 比如说 :
102+ 例如 :
103103
104- - ` pattern:[^aeyo] ` —— 匹配任何除了 ` 'a' ` 、` 'e' ` 、` 'y' ` 或者 ` 'o' ` 之外的字符 。
105- - ` pattern:[^0-9] ` —— 匹配任何除了数字之外的字符,也可以使用 ` \D ` 来表示 。
106- - ` pattern:[^\s] ` —— 匹配任何非空字符,也可以使用 ` \S ` 来表示 。
104+ - ` pattern:[^aeyo] ` —— 匹配除了 ` 'a' ` 、` 'e' ` 、` 'y' ` 或 ` 'o' ` 之外的任何字符 。
105+ - ` pattern:[^0-9] ` —— 匹配除了数字之外的任何字符,与 ` \D ` 作用相同 。
106+ - ` pattern:[^\s] ` —— 匹配任何非空格字符,与 ` \S ` 作用相同 。
107107
108- 下面的示例查询除了字母,数字和空格之外的任意字符 :
108+ 下面的示例搜索除了字母、数字和空格之外的任何字符 :
109109
110110``` js run
111111alert ( " alice15@gmail.com" .match (/ [^ \d\s A-Z ] / gi ) ); // @ and .
112112```
113113
114- ## 在 [ …] 中不转义
114+ ## [ …] 中的转义
115115
116- 通常当我们的确需要查询点字符时,我们需要把它转义成像 ` pattern:\. ` 这样的形式。如果我们需要查询一个反斜杠,我们需要使用 ` pattern:\\ ` 。
116+ 通常当我们想要准确地找到一个特殊字符时,我们需要像 ` pattern:\. ` 这样对其进行转义。如果我们需要反斜杠,那么我们需要使用 ` pattern:\\ ` ,等等 。
117117
118- 在方括号表示中,绝大多数特殊字符可以在不转义的情况下使用 :
118+ 在方括号,我们可以使用绝大多数特殊字符而无需转义 :
119119
120- - 表示一个点符号 ` pattern:'.' ` 。
121- - 表示一个加号 ` pattern:'+' ` 。
122- - 表示一个括号 ` pattern:'( )' ` 。
123- - 在开头或者结尾表示一个破折号(在这些位置该符号表示的就不是一个范围) `pattern:'-'。
124- - 在不是开头的位置表示一个插入符号(在开头位置该符号表示的是排除)` pattern:'^' ` 。
125- - 表示一个开口的方括号符号 ` pattern:'[' ` 。
120+ - 符号 ` pattern:. + ( ) ` 无需转义。
121+ - 在开头或结尾(未定义范围)的连字符 ` pattern:- ` 不会被转义。
122+ - 插入符号 ` pattern:^ ` 仅在开头会被转义(表示排除)。
123+ - 右方括号 ` pattern:] ` 总是会被转义(如果我们需要寻找那个符号)。
126124
127- 换句话说,除了在方括号中有特殊含义的字符外,其它所有特殊字符都是允许不添加反斜杠的 。
125+ 换句话说,除了在方括号中有特殊含义的字符外,其它所有特殊字符都是允许不转义的 。
128126
129- 一个在方括号中的点符号 ` "." ` 表示的就是一个点字符。查询模式 ` pattern:[.,] ` 将会寻找一个为点或者逗号的字符 。
127+ 方括号中的点 ` . ` 表示的就是一个点。模式 ` pattern:[.,] ` 将会搜索字符之一:点或逗号 。
130128
131- 在下面的示例中,` pattern:[-().^+] ` 会查找 ` -().^+ ` 的其中任意一个字符 :
129+ 在下面的示例中,正则表达式 ` pattern:[-().^+] ` 查找 ` -().^+ ` 中的任何字符 :
132130
133131``` js run
134- // 并不需要转义
132+ // 不需要转义
135133let reg = / [-(). ^+] / g ;
136134
137135alert ( " 1 + 2 - 3" .match (reg) ); // 匹配 +,-
138136```
139137
140- 。。。 但是如果你为了“以防万一”转义了它们,这也不会有任何问题:
138+ …… 但是如果你为了“以防万一”转义了它们,这也不会有任何问题:
141139
142140``` js run
143- // 转义其中的所有字符
141+ // 转义其中的所有字符
144142let reg = / [\-\( \)\.\^\+ ] / g ;
145143
146144alert ( " 1 + 2 - 3" .match (reg) ); // 仍能正常工作:+,-
147145```
148146
149- ## 范围和标志“u”
147+ ## 范围和修饰符 "u"
150148
151- 如果集合中有代理对(surrogate pairs),则需要标志 ` pattern:u ` 以使其正常工作 。
149+ 如果集合中有代理对(surrogate pairs),则需要标志 ` pattern:u ` 才能使它们正常工作 。
152150
153151例如,让我们在字符串 ` subject:𝒳 ` 中查找 ` pattern:[𝒳𝒴] ` :
154152
155153``` js run
156- alert ( ' 𝒳' .match (/ [𝒳𝒴] / ) ); // 显示一个奇怪的字符 ,像 [?]
154+ alert ( ' 𝒳' .match (/ [𝒳𝒴] / ) ); // 显示了一个奇怪的字符 ,像 [?]
157155// (搜索执行不正确,返回了半个字符)
158156```
159157
160158结果不正确,因为默认情况下正则表达式“不知道”代理对。
161159
162- 正则表达式引擎认为 ` [𝒳𝒴] ` —— 不是两个 ,而是四个字符:
163- 1 . ` 𝒳 ` ` (1) ` 的左半部分 ,
164- 2 . ` 𝒳 ` ` (2) ` 的右半部分 ,
165- 3 . ` 𝒴 ` ` (3) ` 的左半部分 ,
166- 4 . ` 𝒴 ` ` (4) ` 的右半部分 。
160+ 正则表达式引擎认为 ` [𝒳𝒴] ` —— 不是两个字符 ,而是四个字符:
161+ 1 . ` 𝒳 ` 的左半部分 ` (1) ` ,
162+ 2 . ` 𝒳 ` 的右半部分 ` (2) ` ,
163+ 3 . ` 𝒴 ` 的左半部分 ` (3) ` ,
164+ 4 . ` 𝒴 ` 的右半部分 ` (4) ` 。
167165
168- 我们可以看到它们的代码 ,如下所示:
166+ 我们可以看到它们的编码 ,如下所示:
169167
170168``` js run
171169for (let i= 0 ; i< ' 𝒳𝒴' .length ; i++ ) {
172170 alert (' 𝒳𝒴' .charCodeAt (i)); // 55349, 56499, 55349, 56500
173171};
174172```
175173
176- 因此,以上示例查找并显示了 ` 𝒳 ` 的左半部分。
174+ 因此,上面的示例查找并显示了 ` 𝒳 ` 的左半部分。
177175
178- 如果我们添加标志 ` pattern:u ` ,那么行为将是正确的 :
176+ 如果我们添加了修饰符 ` pattern:u ` ,那么行为就正常了 :
179177
180178``` js run
181179alert ( ' 𝒳' .match (/ [𝒳𝒴] / u ) ); // 𝒳
182180```
183181
184182当我们查找范围时也会出现类似的情况,就像 ` [𝒳-𝒴] ` 。
185183
186- 如果我们忘记添加标志 ` pattern:u ` ,则会出现错误:
184+ 如果我们忘记添加修饰符 ` pattern:u ` ,则会出现错误:
187185
188186``` js run
189- ' 𝒳' .match (/ [𝒳-𝒴 ] / ); // 错误:无效的正则表达式
187+ ' 𝒳' .match (/ [𝒳-𝒴 ] / ); // Error: Invalid regular expression
190188```
191189
192- 原因是,没有标志 ` pattern:u ` 的代理对被视为两个字符,因此 ` [𝒳-𝒴] ` 被解释为 ` [<55349><56499>-<55349><56500>] ` (每个代理对都替换为其代码)。现在很容易看出范围 ` 56499-55349 ` 是无效的:其起始代码 ` 56499 ` 大于终止代码 ` 55349 ` 。这就是错误的原因。
190+ 因为,没有修饰符 ` pattern:u ` 时,代理对将被视为两个字符,所以 ` [𝒳-𝒴] ` 被理解为 ` [<55349><56499>-<55349><56500>] ` (每个代理对都替换为其代码)。现在很容易看出范围 ` 56499-55349 ` 是无效的:其起始代码 ` 56499 ` 大于终止代码 ` 55349 ` 。这就是错误的原因。
193191
194- 使用标志 ` pattern:u ` ,该模式可以正常匹配 :
192+ 带有修饰符 ` pattern:u ` 时,该模式就可以正常匹配了 :
195193
196194``` js run
197- // 查找字符从 𝒳 到 𝒵
195+ // 查找从 𝒳 到 𝒵 的字符
198196alert ( ' 𝒴' .match (/ [𝒳-𝒵 ] / u ) ); // 𝒴
199197```
0 commit comments