Skip to content

Commit fe5e5f0

Browse files
committed
feat: update translation
1 parent e8e8772 commit fe5e5f0

File tree

5 files changed

+79
-46
lines changed

5 files changed

+79
-46
lines changed

9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/solution.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
整数的正则表达式是 `pattern:\d+`
33

4-
我们可以通过在它前面加上否定的后行断言来排除负数:`表达式:(?<!-)\d+`
4+
我们可以通过在它前面加上否定的后瞻断言来排除负数:`pattern:(?<!-)\d+`
55

6-
尽管如此,如果我们现在尝试使用上面的表达式,会发现有一个“例外”情况:
6+
尽管如此,如果我们现在尝试使用上面的正则表达式,会发现有一个“例外”情况:
77

88
```js run
99
let regexp = /(?<!-)\d+/g;
@@ -15,9 +15,9 @@ console.log( str.match(regexp) ); // 0, 12, 123, *!*8*/!*
1515

1616
正如我们所看到的,它从 `subject:-18` 中配到了 `match:8`。要排除这种情况,我们需要确保正则表达式要从一个数的开头开始匹配数字,而不是从另一个(不匹配的)数字的中间开始进行匹配。
1717

18-
我们可以通过指定另一个否定的后行断言来实现这一点`pattern:(?<!-)(?<!\d)\d+`。现在 `pattern:(?<!\d)` 确保匹配不会从另一个数字之后开始进行匹配了,这正是我们所需要的。
18+
我们可以通过指定另一个否定的后瞻断言来实现这一点`pattern:(?<!-)(?<!\d)\d+`。现在 `pattern:(?<!\d)` 确保匹配不会从另一个数字之后开始进行匹配了,这正是我们所需要的。
1919

20-
我们也可以把它们合并为一个后行断言
20+
我们也可以把它们合并成一个后瞻断言
2121

2222
```js run
2323
let regexp = /(?<![-\d])\d+/g;

9-regular-expressions/14-regexp-lookahead-lookbehind/1-find-non-negative-integers/task.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
创建一个正则表达式来找出所有的非负整数(包括 0)。
66

77
使用示例:
8-
98
```js
109
let regexp = /你的正则表达式/g;
1110

9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/solution.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
为了在 `<body>` 标签后面插入内容,我们必须先找到它。我们可以使用正则表达式模式 `pattern:<body.*?>` 来实现。
1+
为了在 `<body>` 标签后面插入内容,我们必须先找到它。我们可以使用正则表达式 `pattern:<body.*?>` 来实现。
22

3-
在本题目中,我们不需要修改 `<body>` 标签。我们只需要在它后面添加文本。
3+
在本任务中,我们不需要修改 `<body>` 标签。我们只需要在它后面添加文本。
44

55
我们可以这样做:
66

@@ -13,7 +13,7 @@ alert(str); // ...<body style="..."><h1>Hello</h1>...
1313

1414
在替换字符串中,`$&` 表示匹配本身,即源文本中与 `pattern:<body.*?>` 相对应的部分。它会被它自身加上 `<h1>Hello</h1>` 替换。
1515

16-
另一种方法是使用后行断言
16+
另一种方法是使用后瞻断言
1717

1818
```js run
1919
let str = '...<body style="...">...';
@@ -22,7 +22,7 @@ str = str.replace(/(?<=<body.*?>)/, `<h1>Hello</h1>`);
2222
alert(str); // ...<body style="..."><h1>Hello</h1>...
2323
```
2424

25-
正如你所看到的,这个正则表达式中只有后行断言部分
25+
正如你所看到的,这个正则表达式中只有后瞻断言部分
2626

2727
它的工作原理如下:
2828
- 在文本的每个位置。
@@ -33,4 +33,4 @@ alert(str); // ...<body style="..."><h1>Hello</h1>...
3333

3434
因此,它将紧挨着 `pattern:<body.*?>` 的“空位置”替换为了 `<h1>Hello</h1>`。这样就在 `<body>` 之后插入了内容。
3535

36-
P.S. 正则表达式中修饰符(flag)例如 `pattern:s``pattern:i` 也很有用:`pattern:/<body.*?>/si`。这里修饰符(flag)`pattern:s` 使得 `.` 可以匹配换行符,而修饰符 `pattern:i` 使 `pattern:<body>` 大小写不敏感,可以匹配 `match:<BODY>`
36+
P.S. 正则表达式中的修饰符,例如 `pattern:s``pattern:i` 也很有用:`pattern:/<body.*?>/si`。这里修饰符 `pattern:s` 使得 `.` 可以匹配换行符,而修饰符 `pattern:i` 使 `pattern:<body>` 大小写不敏感,可以匹配 `match:<BODY>`

9-regular-expressions/14-regexp-lookahead-lookbehind/2-insert-after-head/task.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ str = str.replace(regexp, `<h1>Hello</h1>`);
2121
```
2222

2323
之后,`str` 的值应该为:
24+
2425
```html
2526
<html>
2627
<body style="height: 200px"><h1>Hello</h1>
Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,134 @@
11
# 前瞻断言与后瞻断言
22

3-
有时候我们需要匹配后面跟着特定模式的一段模式。比如,我们要从 `subject:1 turkey costs 30€` 这段字符中匹配价格数值
3+
有时我们只需要为一个模式找到那些在另一个模式之后或之前的匹配项
44

5-
我们需要获取 `subject:€` 符号前面的数值(假设价格是整数)
5+
有一种特殊的语法,称为“前瞻断言(lookahead)”和“后瞻断言(lookbehind)”
66

7-
那就是前瞻断言要做的事情
7+
首先,让我们从字符串中查找价格,例如 `subject:1 turkey costs 30€`。即:一个数字,后跟`subject:€`符号
88

99
## 前瞻断言
1010

11-
语法为:`pattern:x(?=y)`,它表示“仅在后面是 `pattern:y` 的情况匹配 `pattern:x`”。
11+
语法为:`pattern:x(?=y)`,它表示“仅在后面是 `pattern:Y` 时匹配 `pattern:X`”。There may be any pattern instead of `pattern:X` and `pattern:Y`.
1212

13-
那么对于一个后面跟着 `` 的整数金额,它的正则表达式应该为`pattern:\d+(?=€)`
13+
那么对于一个后面跟着 `` 的整数,正则表达式应该为`pattern:\d+(?=€)`
1414

1515
```js run
1616
let str = "1 turkey costs 30€";
1717

18-
alert( str.match(/\d+(?=€)/) ); // 30 (正确地跳过了单个的数字 1)
18+
alert( str.match(/\d+(?=€)/) ); // 30,数字 1 被忽略了,因为它后面没有 €
1919
```
2020

21-
让我们来看另一种情况:这次我们想要一个数量,它是一个不被 `subject:€` 跟着的数值
21+
请注意:前瞻断言只是一个测试,括号 `pattern:(?=...)` 中的内容不包含在匹配结果 `match:30`
2222

23-
这里就要用到前瞻否定断言了
23+
当我们查找 `pattern:X(?=Y)` 时,正则表达式引擎会找到 `pattern:X`,然后检查其后是否有 `pattern:Y`。如果没有,则跳过潜在匹配,并继续搜索
2424

25-
语法为:`pattern:x(?!y)`,意思是 "查找 `pattern:x`, 但是仅在不被 `pattern:y` 跟随的情况下匹配成功"。
25+
更复杂的测试也是可能的,例如 `pattern:X(?=Y)(?=Z)` 表示:
26+
27+
1. 寻找 `pattern:X`
28+
2. 检查 `pattern:Y` 是否紧跟在 `pattern:X` 之后(如果不是则跳过)。
29+
3. 检查 `pattern:Z` 是否也在 `pattern:X` 之后(如果不是则跳过)。
30+
4. 如果两个测试都通过了,那么 `pattern:X` 是匹配的,否则继续搜索。
31+
32+
换句话说,这样的模式意味着我们同时在寻找 `pattern:X` 后跟 `pattern:Y``pattern:Z`
33+
34+
这只有在模式 `pattern:Y``pattern:Z` 不是互斥的情况下才可行。
35+
36+
例如,`pattern:\d+(?=\s)(?=.*30)` 查找后跟着空格 `pattern:(?=\s)``pattern:\d+`,并且有 ` 30` 在它之后的某个地方 `pattern:(?=.*30)`
37+
38+
```js run
39+
let str = "1 turkey costs 30€";
40+
41+
alert( str.match(/\d+(?=\s)(?=.*30)/) ); // 1
42+
```
43+
44+
在我们给出的字符串中,与数字 `1` 完全匹配。
45+
46+
## 否定的前瞻断言
47+
48+
假设我们想要一个数量,而不是来自同一字符串的价格。那是一个数字 `pattern:\d+`,后面不是 `subject:€`
49+
50+
为此,我们可以使用否定的前瞻断言。
51+
52+
语法是:`pattern:X(?!Y)`,意思是“搜索 `pattern:X`,但前提是后面没有 `pattern:Y`”。
2653

2754
```js run
2855
let str = "2 turkeys cost 60€";
2956

30-
alert( str.match(/\d+(?!€)/) ); // 2(正确地跳过了价格
57+
alert( str.match(/\d+\b(?!€)/g) ); // 2(价格不匹配
3158
```
3259

3360
## 后瞻断言
3461

62+
```warn header="后瞻断言的浏览器兼容情况"
63+
请注意:非 V8 引擎的浏览器不支持后瞻断言,例如 Safari、Internet Explorer。
64+
```
65+
3566
前瞻断言允许添加一个“后面要跟着什么”的条件判断。
3667

37-
后瞻断言也是类似的,只不过它是在相反的方向上进行条件判断。也就是说,它只允许匹配前面有特定字符串的模式。
68+
后瞻断言也类似,只不过它是在相反的方向上进行条件判断。也就是说,它只允许匹配前面有特定字符串的模式。
3869

39-
语法为:
40-
- 后瞻肯定断言`pattern:(?<=y)x`, 匹配 `pattern:x`, 仅在前面是 `pattern:y` 的情况
41-
- 后瞻否定断言`pattern:(?<!y)x`, 匹配 `pattern:x`, 仅在前面不是 `pattern:y` 的情况
70+
语法为如下:
71+
- 肯定的后瞻断言`pattern:(?<=Y)X`匹配 `pattern:X`仅在前面是 `pattern:Y` 的情况下
72+
- 否定的后瞻断言`pattern:(?<!Y)X`匹配 `pattern:X`仅在前面不是 `pattern:Y` 的情况下
4273

43-
举个例子,让我们把价格换成美元。美元符号通常在数字之前,所以要查找 `$30` 我们将使用 `pattern:(?<=\$)\d+` —— 一个前面带 `subject:$` 的数值:
74+
例如,让我们把价格换成美元。美元符号通常在数字前面,所以要查找 `$30` 我们将使用 `pattern:(?<=\$)\d+` —— 一个前面带 `subject:$` 的数值:
4475

4576
```js run
4677
let str = "1 turkey costs $30";
4778

48-
alert( str.match(/(?<=\$)\d+/) ); // 30 (跳过了单个的数字 1)
79+
// 美元符号被转义 \$
80+
alert( str.match(/(?<=\$)\d+/) ); // 30(跳过了仅仅是数字的值)
4981
```
5082

51-
另外,为了找到数量 —— 一个前面不带 `subject:$` 的数字,我们可以使用否定后瞻断言`pattern:(?<!\$)\d+`
83+
如果我们需要找到量词 —— 一个前面不带 `subject:$` 的数字,我们可以使用否定的后瞻断言`pattern:(?<!\$)\d+`
5284

5385
```js run
5486
let str = "2 turkeys cost $60";
5587

56-
alert( str.match(/(?<!\$)\d+/) ); // 2 (跳过了价格)
88+
alert( str.match(/(?<!\$)\b\d+/g) ); // 2(价格不匹配)
5789
```
5890

5991
## 捕获组
6092

61-
一般来说,环视断言括号中(前瞻和后瞻的通用名称)的内容不会成为匹配到的一部分结果
93+
一般来说,前瞻断言和后瞻断言括号中的内容不会成为结果的一部分
6294

63-
例如在模式 `pattern:\d+(?!€)` 中,`pattern:€` 符号就不会出现在匹配结果中。
95+
例如在模式 `pattern:\d+(?!€)` 中,`pattern:€` 符号就不会出现在匹配结果中。这是很自然的事:我们寻找一个数字 `pattern:\d+`,而 `pattern:(?=€)` 只是一个测试,表示要匹配的数字后面应该紧跟着 `subject:€` 字符
6496

65-
但是如果我们想要捕捉整个环视表达式或其中的一部分,那也是有可能的。只需要将其包裹在另加的括号中
97+
但在某些情况下,我们可能还想捕获前瞻断言和后瞻断言所匹配的内容,或者部分内容。这也是可行的。只需要将该部分包装在额外的括号中
6698

67-
例如,这里货币符号 `pattern:(€|kr)` 和金额一起被捕获了:
99+
在下面的示例中,货币符号 `pattern:(€|kr)` 和金额一起被捕获了:
68100

69101
```js run
70102
let str = "1 turkey costs 30€";
71-
let reg = /\d+(?=(€|kr))/; // €|kr 两边有额外的括号
103+
let regexp = /\d+(?=(€|kr))/; // €|kr 两侧有额外的括号
72104

73-
alert( str.match(reg) ); // 30, €
105+
alert( str.match(regexp) ); // 30, €
74106
```
75107

76108
后瞻断言也一样:
77109

78110
```js run
79111
let str = "1 turkey costs $30";
80-
let reg = /(?<=(\$|£))\d+/;
112+
let regexp = /(?<=(\$|£))\d+/;
81113

82-
alert( str.match(reg) ); // 30, $
114+
alert( str.match(regexp) ); // 30, $
83115
```
84116

85-
86117
## 总结
87118

88-
当我们想根据前面/后面的上下文筛选出一些东西的时候,前瞻断言和后瞻断言(通常被称为“环视断言”)对于简单的正则表达式就很有用。
119+
当我们想根据前面/后面的上下文匹配某些内容的时候,前瞻断言和后瞻断言(通常被称为“环视断言”)很有用。
120+
121+
对于简单的正则表达式,我们可以手动执行类似的操作。即:不管上下文,匹配所有可匹配的内容,然后在循环中根据上下文进行过滤。
89122

90-
有时我们可以手动处理来得到相同的结果,即:匹配所有,然后在循环中按上下文进行筛选。请记住,`str.matchAll``reg.exec` 返回的匹配结果有 `.index` 属性,因此我们能知道它在文本中的确切位置。但通常正则表达式可以做得更好
123+
请记住,`str.match`(没有修饰符 `pattern:g`)和 `str.matchAll`(总是)将匹配项作为具有 `index` 属性的数组返回,因此我们知道它在文本中的确切位置,并且可以检查上下文
91124

92-
环视断言类型:
125+
但通常环视断言更方便。
126+
127+
环视断言类型:
93128

94129
| 模式 | 类型 | 匹配 |
95130
|--------------------|------------------|---------|
96-
| `pattern:x(?=y)` | 前瞻肯定断言 | `x` ,仅当后面跟着 `y` |
97-
| `pattern:x(?!y)` | 前瞻否定断言 | `x` ,仅当后面不跟 `y` |
98-
| `pattern:(?<=y)x` | 后瞻肯定断言 | `x` ,仅当跟在 `y` 后面 |
99-
| `pattern:(?<!y)x` | 后瞻否定断言 | `x` ,仅当不跟在 `y` 后面 |
100-
101-
前瞻断言也可用于禁用回溯。为什么它是需要的 - 请看下一章。
131+
| `X(?=Y)` | 肯定的前瞻断言 | `pattern:X` 后紧跟着 `pattern:Y` |
132+
| `X(?!Y)` | 否定的前瞻断言 | `pattern:X` 后没紧跟着 `pattern:Y` |
133+
| `(?<=Y)X` | 肯定的后瞻断言 | `pattern:X` 紧跟在 `pattern:Y` 后面 |
134+
| `(?<!Y)X` | 否定的后瞻断言 | `pattern:X` 没紧跟在 `pattern:Y` 后面 |

0 commit comments

Comments
 (0)