From df97553d2b846db87f83bbef171990500245eb23 Mon Sep 17 00:00:00 2001
From: fixiabis <fixiabis@gmail.com>
Date: Mon, 12 Apr 2021 16:41:59 +0800
Subject: [PATCH 1/4] Patterns and flags

---
 .../01-regexp-introduction/article.md         | 151 +++++++++---------
 1 file changed, 72 insertions(+), 79 deletions(-)

diff --git a/9-regular-expressions/01-regexp-introduction/article.md b/9-regular-expressions/01-regexp-introduction/article.md
index a35d19a7b..9335b1967 100644
--- a/9-regular-expressions/01-regexp-introduction/article.md
+++ b/9-regular-expressions/01-regexp-introduction/article.md
@@ -1,108 +1,101 @@
-# Patterns and flags
+# 樣式(Patterns)與 旗標(flags)
 
-Regular expressions are patterns that provide a powerful way to search and replace in text.
+正規表達式(Regular expressions)是提供一種有力的方式在文字上去搜尋與取代的模式。
 
-In JavaScript, they are available via the [RegExp](mdn:js/RegExp) object, as well as being integrated in methods of strings.
+在 JavaScript,它們可以藉由 [RegExp](mdn:js/RegExp) 物件使用,也整合進了字串的方法中。
 
-## Regular Expressions
+## 正規表達式
 
-A regular expression (also "regexp", or just "reg") consists of a *pattern* and optional *flags*.
+一個正規表達式(又稱 "regexp",或只寫做 "reg")由一個**樣式**與可選用的**旗標**組成。
 
-There are two syntaxes that can be used to create a regular expression object.
+這裡有兩種語法可以用來建立一個正規表達式物件。
 
-The "long" syntax:
+較長的語法:
 
 ```js
 regexp = new RegExp("pattern", "flags");
 ```
 
-And the "short" one, using slashes `"/"`:
+和較短的,使用斜線 `"/"`:
 
 ```js
-regexp = /pattern/; // no flags
-regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
+regexp = /pattern/; // 沒有旗標
+regexp = /pattern/gmi; // 搭配旗標 g、m 和 i (等一下會講到)
 ```
 
-Slashes `pattern:/.../` tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings.
+斜線 `pattern:/.../` 會告訴 JavaScript 我們要建立一個正規表達式。它們扮演著跟字串引號相同的角色。
 
-In both cases `regexp` becomes an instance of the built-in `RegExp` class.
+兩種請況下的 `regexp` 都會變成內建 `RegExp` 類別的實體。
 
-The main difference between these two syntaxes is that pattern using slashes `/.../` does not allow for expressions to be inserted (like string template literals with `${...}`). They are fully static.
+兩種語法主要不同之處在於一種使用斜線 `/.../`,不允許插入表達式(像是字串樣板字面值 `${...}`)。他們是完全靜態的。
 
-Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp`, is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance:
+斜線用在當我們撰寫程式碼時,所知道的正規表達式 -- 這是最常見的情況。而 `new RegExp`,經常用在我們需要用動態產生的字串建立一個 '即時' 的正規表達式。例如:
 
 ```js
 let tag = prompt("What tag do you want to find?", "h2");
 
-let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above
+let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則等同 /<h2>/
 ```
 
-## Flags
+## 旗標
 
-Regular expressions may have flags that affect the search.
+正規表達式可能會有影響搜尋結果的旗標。
 
-There are only 6 of them in JavaScript:
+在 JavaScript 中只有6種:
 
-`pattern:i`
-: With this flag the search is case-insensitive: no difference between `A` and `a` (see the example below).
+`pattern:i`:使用這個旗標會使搜尋不區分大小寫:`A` 與 `a` 不分(參見下面的範例)
 
-`pattern:g`
-: With this flag the search looks for all matches, without it -- only the first match is returned.
+`pattern:g`:使用這個旗標會使搜尋查找所有匹配結果, 沒有這個的話 -- 只有第一個匹配結果會回傳。
+搜尋
+`pattern:m`:多行模式 (介紹在此章節 <info:regexp-multiline-mode>)。
 
-`pattern:m`
-: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).
+`pattern:s`:啟用 "dotAll" 模式, 允許句點符號 `pattern:.` 去匹配換行字元 `\n`(介紹在此章節 <info:regexp-character-classes>)。
 
-`pattern:s`
-: Enables "dotall" mode, that allows a dot `pattern:.` to match newline character `\n` (covered in the chapter <info:regexp-character-classes>).
+`pattern:u`:啟用完整 unicode 支援。該旗標啟用了正確的代理對(surrogate pairs)處理。關於更多在此章節 <info:regexp-unicode>。
 
-`pattern:u`
-: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
+`pattern:y`:"Sticky" 模式:搜尋在文本中的確切位置(介紹在此章節 <info:regexp-sticky>)
 
-`pattern:y`
-: "Sticky" mode: searching at the exact position in the text  (covered in the chapter <info:regexp-sticky>)
+```smart header="顏色"
+這裡的配色方式是:
 
-```smart header="Colors"
-From here on the color scheme is:
-
-- regexp -- `pattern:red`
-- string (where we search) -- `subject:blue`
-- result -- `match:green`
+- 正規表達式 -- `pattern:紅色`
+- 字串(我們搜尋的) -- `subject:藍色`
+- 匹配結果 -- `match:綠色`
 ```
 
-## Searching: str.match
+## 搜尋: str.match
 
-As mentioned previously, regular expressions are integrated with string methods.
+前面有提到,正規表達式有整合在字串的方法。
 
-The method `str.match(regexp)` finds all matches of `regexp` in the string `str`.
+`str.match(regexp)` 方法用 `regexp` 正規表達式尋找了匹配結果在整個 `str` 字串中。
 
-It has 3 working modes:
+它有3種工作模式:
 
-1. If the regular expression has flag `pattern:g`, it returns an array of all matches:
+1. 如果正規表達式有旗標 `pattern:g`,此回傳一個全部匹配結果的陣列:
     ```js run
     let str = "We will, we will rock you";
 
-    alert( str.match(/we/gi) ); // We,we (an array of 2 substrings that match)
+    alert( str.match(/we/gi) ); // We,we (2 個匹配結果的部份字串在一個陣列)
     ```
-    Please note that both `match:We` and `match:we` are found, because flag `pattern:i` makes the regular expression case-insensitive.
+    請注意兩個 `match:We` 和 `match:we` 會被找到,是因為旗標 `pattern:i` 使正規表達式不分大小寫。
 
-2. If there's no such flag it returns only the first match in the form of an array, with the full match at index `0` and some additional details in properties:
+2. 如果沒有旗標 `pattern:g` 回傳形式會是只有第一個匹配結果的陣列,該陣列中包含一些額外資訊在屬性中,完全匹配結果在索引 `0`:
     ```js run
     let str = "We will, we will rock you";
 
-    let result = str.match(/we/i); // without flag g
+    let result = str.match(/we/i); // 不使用旗標 g
 
-    alert( result[0] );     // We (1st match)
+    alert( result[0] );     // We (1st 匹配結果)
     alert( result.length ); // 1
 
-    // Details:
-    alert( result.index );  // 0 (position of the match)
-    alert( result.input );  // We will, we will rock you (source string)
+    // 額外資訊:
+    alert( result.index );  // 0 (匹配位置)
+    alert( result.input );  // We will, we will rock you (來源字串)
     ```
-    The array may have other indexes, besides `0` if a part of the regular expression is enclosed in parentheses. We'll cover that in the chapter  <info:regexp-groups>.
-
-3. And, finally, if there are no matches, `null` is returned (doesn't matter if there's flag `pattern:g` or not).
+    如果正規表達式的一部分在括号中,則陣列除了 `0` 外還會有其他索引。我們將在此章節介紹 <info:regexp-groups>。
 
-    This a very important nuance. If there are no matches, we don't receive an empty array, but instead receive `null`. Forgetting about that may lead to errors, e.g.:
+3. 最後,如果沒有匹配結果,會回傳 `null`(與有無 `pattern:g` 旗標無關)。
+    這是很重要的細節。如果沒有匹配結果,我們不會收到一個空陣列,而是收到 `null`。忘記這件事情會導致錯誤,例如:
 
     ```js run
     let matches = "JavaScript".match(/HTML/); // = null
@@ -112,50 +105,50 @@ It has 3 working modes:
     }
     ```
 
-    If we'd like the result to always be an array, we can write it this way:
+    如果我們想要結果永遠是一個陣列,我們可以這麼寫:
 
     ```js run
     let matches = "JavaScript".match(/HTML/)*!* || []*/!*;
 
     if (!matches.length) {
-      alert("No matches"); // now it works
+      alert("No matches"); // 現在會動了
     }
     ```
 
-## Replacing: str.replace
+## 取代: str.replace
 
-The method `str.replace(regexp, replacement)` replaces matches found using `regexp` in string `str` with `replacement` (all matches if there's flag `pattern:g`, otherwise, only the first one).
+`str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串使用 `placement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
 
-For instance:
+例如:
 
 ```js run
-// no flag g
+// 沒有 g 旗標
 alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
 
-// with flag g
+// 有 g 旗標
 alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
 ```
 
-The second argument is the `replacement` string. We can use special character combinations in it to insert fragments of the match:
+第二個參數是 `replacement` 字串。我們可以在其中使用特殊字元组来插入匹配結果片段:
 
-| Symbols | Action in the replacement string |
+| 符號 | 取代字串的操作 |
 |--------|--------|
-|`$&`|inserts the whole match|
-|<code>$&#096;</code>|inserts a part of the string before the match|
-|`$'`|inserts a part of the string after the match|
-|`$n`|if `n` is a 1-2 digit number, then it inserts the contents of n-th parentheses, more about it in the chapter <info:regexp-groups>|
-|`$<name>`|inserts the contents of the parentheses with the given `name`, more about it in the chapter <info:regexp-groups>|
-|`$$`|inserts character `$` |
+|`$&`|插入整個匹配結果|
+|<code>$&#096;</code>|插入匹配結果前面的字串|
+|`$'`|插入匹配結果後面的字串|
+|`$n`|如果 `n` 是一個 1 到 2 位元的數字,那會插入第 n 個括號中的內容,關於更多在此章節 <info:regexp-groups>|
+|`$<name>`|插入給定 `name` 括號中的內容, 關於更多在此章節 <info:regexp-groups>|
+|`$$`|插入字元 `$` |
 
-An example with `pattern:$&`:
+`pattern:$&` 的範例:
 
 ```js run
 alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
 ```
 
-## Testing: regexp.test
+## 測試: regexp.test
 
-The method `regexp.test(str)` looks for at least one match, if found, returns `true`, otherwise `false`.
+`regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,回傳 `true`,反之則是 `false`。
 
 ```js run
 let str = "I love JavaScript";
@@ -164,14 +157,14 @@ let regexp = /LOVE/i;
 alert( regexp.test(str) ); // true
 ```
 
-Later in this chapter we'll study more regular expressions, walk through more examples, and also meet other methods.
+之後的章節我們將學惜更多正規表達式,通過更多的範例,了解其他方法。
 
-Full information about the methods is given in the article <info:regexp-methods>.
+關於方法的完整資訊提供在此文章 <info:regexp-methods>。
 
-## Summary
+## 總結
 
-- A regular expression consists of a pattern and optional flags: `pattern:g`, `pattern:i`, `pattern:m`, `pattern:u`, `pattern:s`, `pattern:y`.
-- Without flags and special symbols  (that we'll study later), the search by a regexp is the same as a substring search.
-- The method `str.match(regexp)` looks for matches: all of them if there's `pattern:g` flag, otherwise, only the first one.
-- The method `str.replace(regexp, replacement)` replaces matches found using `regexp` with `replacement`: all of them if there's `pattern:g` flag, otherwise only the first one.
-- The method `regexp.test(str)` returns `true` if there's at least one match, otherwise, it returns `false`.
+- 一個正規表達式由一個樣式和可選用的旗標組成,可選用旗標:`pattern:g`、`pattern:i`、`pattern:m`、`pattern:u`、`pattern:s`、`pattern:y`。
+- 除了旗標和特殊符號(我們等等會學到),用正規表達式來搜尋跟部份字串搜尋相同。
+- `str.match(regexp)` 方法用 `regexp` 正規表達式尋找了匹配結果在整個 `str` 字串中。
+- `str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串中使用 `placement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
+- `regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,回傳 `true`,反之則是 `false`。

From 3f94738725f05858132f2b3330901d5e93e2a589 Mon Sep 17 00:00:00 2001
From: fixiabis <fixiabis@gmail.com>
Date: Mon, 12 Apr 2021 18:13:15 +0800
Subject: [PATCH 2/4] Correction of words, quote style

---
 .../01-regexp-introduction/article.md              | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/9-regular-expressions/01-regexp-introduction/article.md b/9-regular-expressions/01-regexp-introduction/article.md
index 9335b1967..d839eb527 100644
--- a/9-regular-expressions/01-regexp-introduction/article.md
+++ b/9-regular-expressions/01-regexp-introduction/article.md
@@ -29,7 +29,7 @@ regexp = /pattern/gmi; // 搭配旗標 g、m 和 i (等一下會講到)
 
 兩種語法主要不同之處在於一種使用斜線 `/.../`,不允許插入表達式(像是字串樣板字面值 `${...}`)。他們是完全靜態的。
 
-斜線用在當我們撰寫程式碼時,所知道的正規表達式 -- 這是最常見的情況。而 `new RegExp`,經常用在我們需要用動態產生的字串建立一個 '即時' 的正規表達式。例如:
+斜線用在當我們撰寫程式碼時,所知道的正規表達式 -- 這是最常見的情況。而 `new RegExp`,經常用在我們需要用動態產生的字串建立一個 "即時" 的正規表達式。例如:
 
 ```js
 let tag = prompt("What tag do you want to find?", "h2");
@@ -45,7 +45,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
 
 `pattern:i`:使用這個旗標會使搜尋不區分大小寫:`A` 與 `a` 不分(參見下面的範例)
 
-`pattern:g`:使用這個旗標會使搜尋查找所有匹配結果, 沒有這個的話 -- 只有第一個匹配結果會回傳。
+`pattern:g`:使用這個旗標會使搜尋查找所有匹配結果, 沒有這個的話 -- 只有第一個匹配結果會傳回。
 搜尋
 `pattern:m`:多行模式 (介紹在此章節 <info:regexp-multiline-mode>)。
 
@@ -71,7 +71,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
 
 它有3種工作模式:
 
-1. 如果正規表達式有旗標 `pattern:g`,此回傳一個全部匹配結果的陣列:
+1. 如果正規表達式有旗標 `pattern:g`,此傳回一個全部匹配結果的陣列:
     ```js run
     let str = "We will, we will rock you";
 
@@ -79,7 +79,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
     ```
     請注意兩個 `match:We` 和 `match:we` 會被找到,是因為旗標 `pattern:i` 使正規表達式不分大小寫。
 
-2. 如果沒有旗標 `pattern:g` 回傳形式會是只有第一個匹配結果的陣列,該陣列中包含一些額外資訊在屬性中,完全匹配結果在索引 `0`:
+2. 如果沒有旗標 `pattern:g` 傳回形式會是只有第一個匹配結果的陣列,該陣列中包含一些額外資訊在屬性中,完全匹配結果在索引 `0`:
     ```js run
     let str = "We will, we will rock you";
 
@@ -94,7 +94,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
     ```
     如果正規表達式的一部分在括号中,則陣列除了 `0` 外還會有其他索引。我們將在此章節介紹 <info:regexp-groups>。
 
-3. 最後,如果沒有匹配結果,會回傳 `null`(與有無 `pattern:g` 旗標無關)。
+3. 最後,如果沒有匹配結果,會傳回 `null`(與有無 `pattern:g` 旗標無關)。
     這是很重要的細節。如果沒有匹配結果,我們不會收到一個空陣列,而是收到 `null`。忘記這件事情會導致錯誤,例如:
 
     ```js run
@@ -148,7 +148,7 @@ alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and
 
 ## 測試: regexp.test
 
-`regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,回傳 `true`,反之則是 `false`。
+`regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,傳回 `true`,反之則是 `false`。
 
 ```js run
 let str = "I love JavaScript";
@@ -167,4 +167,4 @@ alert( regexp.test(str) ); // true
 - 除了旗標和特殊符號(我們等等會學到),用正規表達式來搜尋跟部份字串搜尋相同。
 - `str.match(regexp)` 方法用 `regexp` 正規表達式尋找了匹配結果在整個 `str` 字串中。
 - `str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串中使用 `placement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
-- `regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,回傳 `true`,反之則是 `false`。
+- `regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,傳回 `true`,反之則是 `false`。

From 09ecc94e96c73b3c03a97d30974cfc150283ac14 Mon Sep 17 00:00:00 2001
From: fixiabis <fixiabis@gmail.com>
Date: Mon, 12 Apr 2021 23:43:35 +0800
Subject: [PATCH 3/4] Change words by suggestions

---
 .../01-regexp-introduction/article.md         | 32 +++++++++----------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/9-regular-expressions/01-regexp-introduction/article.md b/9-regular-expressions/01-regexp-introduction/article.md
index d839eb527..6b5aa701c 100644
--- a/9-regular-expressions/01-regexp-introduction/article.md
+++ b/9-regular-expressions/01-regexp-introduction/article.md
@@ -6,7 +6,7 @@
 
 ## 正規表達式
 
-一個正規表達式(又稱 "regexp",或只寫做 "reg")由一個**樣式**與可選用的**旗標**組成。
+一個正規表達式(又稱 "regexp",或只寫做 "reg")由一個 **樣式** 與可選用的 **旗標** 組成。
 
 這裡有兩種語法可以用來建立一個正規表達式物件。
 
@@ -46,14 +46,14 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
 `pattern:i`:使用這個旗標會使搜尋不區分大小寫:`A` 與 `a` 不分(參見下面的範例)
 
 `pattern:g`:使用這個旗標會使搜尋查找所有匹配結果, 沒有這個的話 -- 只有第一個匹配結果會傳回。
-搜尋
-`pattern:m`:多行模式 (介紹在此章節 <info:regexp-multiline-mode>)。
 
-`pattern:s`:啟用 "dotAll" 模式, 允許句點符號 `pattern:.` 去匹配換行字元 `\n`(介紹在此章節 <info:regexp-character-classes>)。
+`pattern:m`:多行模式 (在此章節 <info:regexp-multiline-mode> 介紹)。
 
-`pattern:u`:啟用完整 unicode 支援。該旗標啟用了正確的代理對(surrogate pairs)處理。關於更多在此章節 <info:regexp-unicode>。
+`pattern:s`:啟用 "dotAll" 模式, 允許句點符號 `pattern:.` 去匹配換行字元 `\n`(在此章節 <info:regexp-character-classes> 介紹)。
 
-`pattern:y`:"Sticky" 模式:搜尋在文本中的確切位置(介紹在此章節 <info:regexp-sticky>)
+`pattern:u`:啟用完整 unicode 支援。該旗標啟用了正確的代理對(surrogate pairs)處理。關於更多資訊會列在此章節 <info:regexp-unicode>。
+
+`pattern:y`:"Sticky" 模式:搜尋在文本中的確切位置(在此章節 <info:regexp-sticky> 介紹)
 
 ```smart header="顏色"
 這裡的配色方式是:
@@ -67,17 +67,17 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
 
 前面有提到,正規表達式有整合在字串的方法。
 
-`str.match(regexp)` 方法用 `regexp` 正規表達式尋找了匹配結果在整個 `str` 字串中。
+`str.match(regexp)` 方法用 `regexp` 正規表達式尋找在整個 `str` 字串中的所有匹配結果。
 
-它有3種工作模式:
+它有 3 種運作模式:
 
 1. 如果正規表達式有旗標 `pattern:g`,此傳回一個全部匹配結果的陣列:
     ```js run
     let str = "We will, we will rock you";
 
-    alert( str.match(/we/gi) ); // We,we (2 個匹配結果的部份字串在一個陣列)
+    alert( str.match(/we/gi) ); // We,we (一個陣列內含 2 個匹配結果的部份字串)
     ```
-    請注意兩個 `match:We` 和 `match:we` 會被找到,是因為旗標 `pattern:i` 使正規表達式不分大小寫。
+    請注意 `match:We` 和 `match:we` 皆被找到,是因為旗標 `pattern:i` 使正規表達式不分大小寫。
 
 2. 如果沒有旗標 `pattern:g` 傳回形式會是只有第一個匹配結果的陣列,該陣列中包含一些額外資訊在屬性中,完全匹配結果在索引 `0`:
     ```js run
@@ -92,7 +92,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
     alert( result.index );  // 0 (匹配位置)
     alert( result.input );  // We will, we will rock you (來源字串)
     ```
-    如果正規表達式的一部分在括号中,則陣列除了 `0` 外還會有其他索引。我們將在此章節介紹 <info:regexp-groups>。
+    如果正規表達式的一部分在括號中,則陣列除了 `0` 外還會有其他索引。我們將在此章節介紹 <info:regexp-groups>。
 
 3. 最後,如果沒有匹配結果,會傳回 `null`(與有無 `pattern:g` 旗標無關)。
     這是很重要的細節。如果沒有匹配結果,我們不會收到一個空陣列,而是收到 `null`。忘記這件事情會導致錯誤,例如:
@@ -117,7 +117,7 @@ let regexp = new RegExp(`<${tag}>`); // 如果在提示窗中回答 "h2",則
 
 ## 取代: str.replace
 
-`str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串使用 `placement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
+`str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串使用 `replacement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
 
 例如:
 
@@ -157,14 +157,14 @@ let regexp = /LOVE/i;
 alert( regexp.test(str) ); // true
 ```
 
-之後的章節我們將學惜更多正規表達式,通過更多的範例,了解其他方法。
+之後的章節我們將學習更多正規表達式,經過更多的範例,了解其他方法。
 
-關於方法的完整資訊提供在此文章 <info:regexp-methods>。
+關於方法的完整資訊在此文章 <info:regexp-methods> 內提供。
 
 ## 總結
 
 - 一個正規表達式由一個樣式和可選用的旗標組成,可選用旗標:`pattern:g`、`pattern:i`、`pattern:m`、`pattern:u`、`pattern:s`、`pattern:y`。
 - 除了旗標和特殊符號(我們等等會學到),用正規表達式來搜尋跟部份字串搜尋相同。
-- `str.match(regexp)` 方法用 `regexp` 正規表達式尋找了匹配結果在整個 `str` 字串中。
-- `str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串中使用 `placement` 字串取代。(如果是 `pattern:g` 旗標的話,會是全部匹配結果,反之只會是第一個)。
+- `str.match(regexp)` 方法尋找這些匹配:若有 `pattern:g` 旗標,找到全部匹配,否則,只找第一個匹配。
+- `str.replace(regexp, replacement)` 方法用 `regexp` 找到了匹配結果,並在 `str` 字串中使用 `replacement` 字串取代。:若有 `pattern:g` 旗標,取代全部匹配結果,反之只取代第一個匹配。
 - `regexp.test(str)` 方法尋找至少一個匹配結果,如果有找到,傳回 `true`,反之則是 `false`。

From 7398d1519c54420f65c8664907ca076218253f12 Mon Sep 17 00:00:00 2001
From: fixiabis <fixiabis@gmail.com>
Date: Thu, 22 Apr 2021 19:22:56 +0800
Subject: [PATCH 4/4] object keys values entries

---
 .../01-sum-salaries/solution.md               |  8 +--
 .../01-sum-salaries/task.md                   | 10 +--
 .../02-count-properties/task.md               |  6 +-
 .../09-keys-values-entries/article.md         | 62 +++++++++----------
 4 files changed, 43 insertions(+), 43 deletions(-)

diff --git a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md
index 27a7b418a..11b1c0205 100644
--- a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md
+++ b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/solution.md
@@ -17,12 +17,12 @@ let salaries = {
 
 alert( sumSalaries(salaries) ); // 650
 ```
-Or, optionally, we could also get the sum using `Object.values` and `reduce`:
+或,我們也可以使用 `Object.values` 和 `reduce` 取得總和:
 
 ```js
-// reduce loops over array of salaries,
-// adding them up
-// and returns the result
+// reduce 遍歷整個薪水的陣列
+// 把它們加總起來
+// 然後傳回結果
 function sumSalaries(salaries) {
   return Object.values(salaries).reduce((a, b) => a + b, 0) // 650
 }
diff --git a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md
index 211357d03..0d742c65b 100644
--- a/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md
+++ b/1-js/05-data-types/09-keys-values-entries/01-sum-salaries/task.md
@@ -2,15 +2,15 @@ importance: 5
 
 ---
 
-# Sum the properties
+# 把屬性加總
 
-There is a `salaries` object with arbitrary number of salaries. 
+這裡有個 `salaries` 物件,有任意的薪水數字。
 
-Write the function `sumSalaries(salaries)` that returns the sum of all salaries using `Object.values` and the `for..of` loop.
+撰寫一個函式 `sumSalaries(salaries)`,該函式使用 `Object.values` 和 `for..of` 迴圈來傳回全部薪水的加總。
 
-If `salaries` is empty, then the result must be `0`.
+如果 `salaries` 是空的,那麼結果必須是 `0`。
 
-For instance:
+例如:
 
 ```js
 let salaries = {
diff --git a/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md b/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md
index d7aebb1fa..bdecc8586 100644
--- a/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md
+++ b/1-js/05-data-types/09-keys-values-entries/02-count-properties/task.md
@@ -4,7 +4,7 @@ importance: 5
 
 # Count properties
 
-Write a function `count(obj)` that returns the number of properties in the object:
+寫一個函式 `count(obj)`,該函式會傳回物件有幾個屬性。
 
 ```js
 let user = {
@@ -15,7 +15,7 @@ let user = {
 alert( count(user) ); // 2
 ```
 
-Try to make the code as short as possible.
+嘗試把程式碼盡可能的變短吧。
 
-P.S. Ignore symbolic properties, count only "regular" ones.
+備註:忽略符號的屬性,只計算 "一般的"。
 
diff --git a/1-js/05-data-types/09-keys-values-entries/article.md b/1-js/05-data-types/09-keys-values-entries/article.md
index 4af192515..99baa61f0 100644
--- a/1-js/05-data-types/09-keys-values-entries/article.md
+++ b/1-js/05-data-types/09-keys-values-entries/article.md
@@ -1,42 +1,42 @@
 
 # Object.keys, values, entries
 
-Let's step away from the individual data structures and talk about the iterations over them.
+我們先忽略個別資料結構,然後來討論關於在他們上面迭代這件事情。
 
-In the previous chapter we saw methods `map.keys()`, `map.values()`, `map.entries()`.
+在前面的章節我們看過 `map.keys()`、`map.values()`、`map.entries()` 方法。
 
-These methods are generic, there is a common agreement to use them for data structures. If we ever create a data structure of our own, we should implement them too.
+這些方法是通用的,這裡通常允許資料結構去使用他們。如果我們曾經建立自有的資料結構,那我們也應該實作他們。
 
-They are supported for:
+他們可以支援:
 
 - `Map`
 - `Set`
 - `Array`
 
-Plain objects also support similar methods, but the syntax is a bit different.
+一般物件也支援類似的方法,但是語法有些不同。
 
 ## Object.keys, values, entries
 
-For plain objects, the following methods are available:
+對於一般物件,有以下的方法可以使用:
 
-- [Object.keys(obj)](mdn:js/Object/keys) -- returns an array of keys.
-- [Object.values(obj)](mdn:js/Object/values) -- returns an array of values.
-- [Object.entries(obj)](mdn:js/Object/entries) -- returns an array of `[key, value]` pairs.
+- [Object.keys(obj)](mdn:js/Object/keys) -- 傳回鍵值陣列。
+- [Object.values(obj)](mdn:js/Object/values) -- 傳回值的陣列。
+- [Object.entries(obj)](mdn:js/Object/entries) -- 傳回 `[key, value]` 組成的陣列。
 
-Please note the distinctions (compared to map for example):
+請注意區別(相較於 map 的範例):
 
 |             | Map              | Object       |
 |-------------|------------------|--------------|
-| Call syntax | `map.keys()`  | `Object.keys(obj)`, but not `obj.keys()` |
-| Returns     | iterable    | "real" Array                     |
+| 呼叫語法 | `map.keys()`  | `Object.keys(obj)`,而不是 `obj.keys()` |
+| 傳回     | 可迭代物件    | "實際的" 陣列                     |
 
-The first difference is that we have to call `Object.keys(obj)`, and not `obj.keys()`.
+第一個區別是我們必須呼叫 `Object.keys(obj)`,而不是 `obj.keys()`。
 
-Why so? The main reason is flexibility. Remember, objects are a base of all complex structures in JavaScript. So we may have an object of our own like `data` that implements its own `data.values()` method. And we still can call `Object.values(data)` on it.
+為何如此?主要原因是彈性。記住,在 JavaScript,所有複雜結構都是基於物件。所以我們可能自己有一個像是 `data` 的物件,該物件實作自有的 `data.values()` 方法。而且我們也可以對該物件呼叫 `Object.values(data)`。
 
-The second difference is that `Object.*` methods return "real" array objects, not just an iterable. That's mainly for historical reasons.
+第二個區別是 `Object.*` 的方法回傳 "實際的" 陣列物件,而不只是一個可迭代物件。這主要是歷史的原因。
 
-For instance:
+例如:
 
 ```js
 let user = {
@@ -49,7 +49,7 @@ let user = {
 - `Object.values(user) = ["John", 30]`
 - `Object.entries(user) = [ ["name","John"], ["age",30] ]`
 
-Here's an example of using `Object.values` to loop over property values:
+這裡有一個使用 `Object.values` 去遍歷所有屬性值的範例:
 
 ```js run
 let user = {
@@ -57,30 +57,30 @@ let user = {
   age: 30
 };
 
-// loop over values
+// 遍歷所有屬性值
 for (let value of Object.values(user)) {
-  alert(value); // John, then 30
+  alert(value); // John, 然後是 30
 }
 ```
 
-```warn header="Object.keys/values/entries ignore symbolic properties"
-Just like a `for..in` loop, these methods ignore properties that use `Symbol(...)` as keys.
+```warn header="Object.keys/values/entries 會忽略符號的屬性"
+就像 `for..in` 迴圈一樣,這些方法會忽略使用 `Symbol(...)` 作為鍵值的屬性。
 
-Usually that's convenient. But if we want symbolic keys too, then there's a separate method [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols) that returns an array of only symbolic keys. Also, there exist a method [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) that returns *all* keys.
+通常來說這很方便。但是,如果我們也需要符號鍵值的話,則有一個區分的方法 [Object.getOwnPropertySymbols](mdn:js/Object/getOwnPropertySymbols),其傳回只有符號鍵值的陣列。另外,還存在一種方法 [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys),則傳回 **全部的** 鍵值。
 ```
 
 
-## Transforming objects
+## 轉換物件
 
-Objects lack many methods that exist for arrays, e.g. `map`, `filter` and others.
+物件缺乏許多存在於陣列的方法,例如 `map`、`filter` 等。
 
-If we'd like to apply them, then we can use `Object.entries` followed `Object.fromEntries`:
+如果我們想應用它們,那麼我們可以使用 `Object.entries` 之後使用 `Object.fromEntries`:
 
-1. Use `Object.entries(obj)` to get an array of key/value pairs from `obj`.
-2. Use array methods on that array, e.g. `map`.
-3. Use `Object.fromEntries(array)` on the resulting array to turn it back into an object.
+1. 使用 `Object.entries(obj)` 從 `obj` 取得鍵與值組合的陣列。
+2. 在該陣列上使用陣列方法,例如 `map`。
+3. 在最終結果的陣列使用 `Object.fromEntries(array)` 轉回成一個物件。
 
-For example, we have an object with prices, and would like to double them:
+例如,我們有個一些價格組成的物件,然後想把它們變兩倍:
 
 ```js run
 let prices = {
@@ -91,7 +91,7 @@ let prices = {
 
 *!*
 let doublePrices = Object.fromEntries(
-  // convert to array, map, and then fromEntries gives back the object
+  // 轉換成陣列,映射,然後以 fromEntries 回給物件
   Object.entries(prices).map(([key, value]) => [key, value * 2])
 );
 */!*
@@ -99,4 +99,4 @@ let doublePrices = Object.fromEntries(
 alert(doublePrices.meat); // 8
 ```   
 
-It may look difficult from the first sight, but becomes easy to understand after you use it once or twice. We can make powerful chains of transforms this way. 
+第一次看到時它看起來會很難懂,但是使用一兩次後,會變得很容易理解。我們可以用這個方式做出有力的轉換鏈式。