Skip to content

Commit e641b4a

Browse files
committed
feat: update translation
1 parent 2a483a5 commit e641b4a

File tree

1 file changed

+50
-39
lines changed

1 file changed

+50
-39
lines changed
Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,55 @@
11

2-
# 粘性标志 "y",在位置处搜索
2+
# 粘性修饰符 "y",在位置处搜索
33

4-
`pattern:y` 标志允许在源字符串中的指定位置执行搜索
4+
`pattern:y` 修饰符让我们能够在源字符串中的指定位置进行搜索
55

6-
为了掌握 `pattern:y` 标志的用例,看看它有多好,让我们来探讨一个实际的用例
6+
为了掌握 `pattern:y` 修饰符的使用方式,让我们来看一个实际的例子
77

8-
regexps 的常见任务之一是"词法分析":比如我们在程序设计语言中得到一个文本,然后分析它的结构元素
8+
正则表达式的常见任务之一就是“词法分析”:例如我们得到了一个代码文本,我们需要找到它的结构元素。例如,HTML 有标签和特性(attribute),JavaScript 代码有函数、变量等
99

10-
例如,HTML 有标签和属性,JavaScript 代码有函数、变量等
10+
编写词法分析器是一个特殊的领域,有自己的工具和算法,所以我们不做过多的深入,但有一个共同的任务:在给定的位置读取一些内容
1111

12-
编写词法分析器是一个特殊的领域,有自己的工具和算法,所以我们就不深究了,但有一个共同的任务:在给定的位置读出一些东西
12+
例如,我们有一个代码字符串 `subject:let varName = "value"`,我们需要从中读取变量名,这个变量名从位置 `4` 开始
1313

14-
例如,我们有一个代码字符串 `subject:let varName = "value"`,我们需要从其中读取变量名,这个变量名从位置 `4` 开始
14+
我们将使用正则表达式 `pattern:\w+` 来查找变量名。实际上,JavaScript 的变量名需要更复杂的正则表达式才能准确匹配,但在这里并不重要
1515

16-
我们用 regexp `pattern:\w+` 来查找变量名。实际上,JavaScript 的变量名需要更复杂的 regexp 来进行准确的匹配,但在这里并不重要。
16+
- 调用 `str.match(/\w+/)` 将只会找到该行中的第一个单词 (`let`)。不是这个。
17+
- 我们可以添加修饰符 `pattern:g`。但是调用 `str.match(/\w+/g)` 会查找文本中的所有单词,而我们需要位置 `4` 的一个单词。同样,不是我们需要的。
1718

18-
调用 `str.match(/\w+/)` 将只找到该行中的第一个单词。或者是所有带标记 `pattern:g` 的单词。但我们只需要在位置 `4` 的一个词
19+
**那么,如何在给定位置准确搜索正则表达式?**
1920

20-
要从给定位置搜索,我们可以使用方法 `regexp.exec(str)`
21+
让我们尝试使用方法 `regexp.exec(str)`
2122

22-
如果 `regexp` 没有标志 `pattern:g` `pattern:y`,那么这个方法就可以寻找字符串 `str` 中的第一个匹配,就像 `str.match(regexp)` 一样。这种简单的无标志的情况我们在这里并不感兴趣
23+
对于没有修饰符 `pattern:g` `pattern:y``regexp`,此方法仅查找第一个匹配项,就像 `str.match(regexp)` 一样。
2324

24-
如果有标志 `pattern:g`那么它就会在字符串 `str` 中执行搜索,从存储在 `regexp.lastIndex` 属性中的位置开始。如果发现匹配,则将 `regexp.lastIndex` 设置为匹配后的索引
25+
……但是如果有修饰符 `pattern:g`那么它就会从存储在 `regexp.lastIndex` 属性中的位置开始在字符串 `str` 中进行搜索。如果找到匹配项,则将在匹配后立即将 `regexp.lastIndex` 设置为索引
2526

26-
当一个 regexp 被创建时,它的 `lastIndex``0`
27+
换句话说,`regexp.lastIndex` 作为搜索的起点,每个 `regexp.exec(str)` 调用都会将其重置为新值(“在最后一次匹配后”)。当然,这只是在有 `pattern:g` 修饰符的情况下才会这样
2728

2829
因此,连续调用 `regexp.exec(str)` 会一个接一个地返回匹配。
2930

30-
一个例子(用标志 `pattern:g`
31+
以下是此类调用的示例
3132

3233
```js run
33-
let str = 'let varName';
34-
34+
let str = 'let varName'; // 让我们找出字符串中的所有单词
3535
let regexp = /\w+/g;
36-
alert(regexp.lastIndex); // 0(最初 lastIndex=0)
36+
37+
alert(regexp.lastIndex); // 0 (初始值 lastIndex=0)
3738

3839
let word1 = regexp.exec(str);
39-
alert(word1[0]); // let第一个单词
40-
alert(regexp.lastIndex); // 3匹配后的位置
40+
alert(word1[0]); // let (第一个单词)
41+
alert(regexp.lastIndex); // 3 (匹配后的位置)
4142

4243
let word2 = regexp.exec(str);
4344
alert(word2[0]); // varName (第二个单词)
44-
alert(regexp.lastIndex); // 11匹配后的位置
45+
alert(regexp.lastIndex); // 11 (匹配后的位置)
4546

4647
let word3 = regexp.exec(str);
47-
alert(word3); // null(没有更多的匹配)
48-
alert(regexp.lastIndex); // 0(搜索结束时重置)
48+
alert(word3); // null (没有更多匹配项)
49+
alert(regexp.lastIndex); // 0 (搜索结束后重置索引)
4950
```
5051

51-
每个匹配都会以数组形式返回,包含分组和附加属性。
52-
53-
我们可以在循环中得到所有的匹配。
52+
我们可以通过循环获取所有匹配。
5453

5554
```js run
5655
let str = 'let varName';
@@ -60,21 +59,23 @@ let result;
6059

6160
while (result = regexp.exec(str)) {
6261
alert( `Found ${result[0]} at position ${result.index}` );
63-
// 在位置 0 发现 let, 然后
62+
// 在位置 0 发现了 let然后
6463
// 在位置 4 发现 varName
6564
}
6665
```
6766

68-
`regexp.exec``str.matchAll` 方法的替代方法。
67+
`regexp.exec` 的这种使用方式可以作为 `str.matchAll` 方法的替代,可以对匹配过程进行更多控制。
68+
69+
让我们回到我们的任务。
6970

70-
与其他方法不同,我们可以设置自己的 `lastIndex`,从给定位置开始搜索。
71+
我们可以手动将 `lastIndex` 设置为 `4`,从给定的位置开始搜索!
7172

72-
例如,让我们从位置 `4` 开始寻找一个单词。
73+
像这样:
7374

7475
```js run
7576
let str = 'let varName = "value"';
7677

77-
let regexp = /\w+/g; // 如果没有标志 "g",属性 lastIndex 会被忽略
78+
let regexp = /\w+/g; // 没有修饰符 "g",lastIndex 属性会被忽略
7879

7980
*!*
8081
regexp.lastIndex = 4;
@@ -84,29 +85,37 @@ let word = regexp.exec(str);
8485
alert(word); // varName
8586
```
8687

87-
我们从位置 `regexp.lastIndex = 4` 开始搜索 `pattern:w+`
88+
哇塞!问题解决了!
8889

89-
请注意:搜索从位置 `lastIndex` 开始,然后再往前走。如果在 `lastIndex` 位置上没有词,但它在后面的某个地方,那么它就会被找到:
90+
我们从位置 `regexp.lastIndex = 4` 开始搜索 `pattern:\w+`
91+
92+
结果是正确的。
93+
94+
……但是等等,没那么快。
95+
96+
请注意:`regexp.exec` 调用从位置 `lastIndex` 开始搜索,然后继续搜索。如果 `lastIndex` 位置没有单词,但单词在这之后的某个位置,那么单词也会被找到:
9097

9198
```js run
9299
let str = 'let varName = "value"';
93100

94101
let regexp = /\w+/g;
95102

96103
*!*
104+
// 从位置 3 开始搜索
97105
regexp.lastIndex = 3;
98106
*/!*
99107

100-
let word = regexp.exec(str);
108+
let word = regexp.exec(str);
109+
// 在位置 4 找到匹配项
101110
alert(word[0]); // varName
102111
alert(word.index); // 4
103112
```
104113

105-
……所以,用标志 `pattern:g` 属性 `lastIndex` 设置搜索的起始位置
114+
对于某些任务,包括词法分析,这是错误的。我们需要在文本的给定位置准确地找到匹配,而不是在它之后的某个位置。这就是修饰符 "y" 的用途
106115

107-
**标记 `pattern:y` 使 `regexp.exec` 正好在 `lastIndex` 位置,而不是在它之前,也不是在它之后**
116+
**修饰符 `pattern:y` 使 `regexp.exec` 精确搜索位置 `lastIndex`,而不是“从”它开始**
108117

109-
下面是使用标志 `pattern:y` 进行同样的搜索。
118+
下面是带有修饰符 `pattern:y` 的相同搜索:
110119

111120
```js run
112121
let str = 'let varName = "value"';
@@ -120,8 +129,10 @@ regexp.lastIndex = 4;
120129
alert( regexp.exec(str) ); // varName(在位置 4 的单词)
121130
```
122131

123-
我们可以看到,regexp `pattern:/\w+/y` 在位置 `3` 处不匹配(不同于标志 `pattern:g` ),而是在位置 `4` 处匹配。
132+
正如我们所看到的,正则表达式 `pattern:/\w+/y` 在位置 `3` 处不匹配(不同于修饰符 `pattern:g`),但在位置 `4` 处匹配。
133+
134+
这不仅是我们所需要的,当使用修饰符 `pattern:y` 时,还有一个重要的性能提升。
124135

125-
想象一下,我们有一个长的文本,而里面根本没有匹配。那么用标志 `pattern:g` 搜索将一直到文本的最后,这将比用标志 `pattern:y` 搜索要花费更多的时间
136+
想象一下,我们有一个很长的文本,其中根本没有匹配项。然后使用修饰符 `pattern:g` 进行搜索,会一直搜索到文本的末尾,并且什么也找不到,这将比使用修饰符 `pattern:y` 的搜索花费更多的时间,后者只检查确切的位置
126137

127-
在像词法分析这样的任务中,通常在一个确切的位置会有很多搜索。使用标志 `pattern:y` 是获得良好性能的关键
138+
在像词法分析这样的任务中,通常会在一个确切的位置进行多次搜索,以检查我们在那里有什么。使用修饰符 `pattern:y` 是正确实现和良好性能的关键

0 commit comments

Comments
 (0)