From 07411850178008c9d24ec0001495fe226204392d Mon Sep 17 00:00:00 2001 From: AceLeeWinnie Date: Sun, 21 Oct 2018 19:07:45 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E7=BF=BB=E8=AF=91=E5=88=9D=E7=A8=BF?= =?UTF-8?q?=EF=BC=9A=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: AceLeeWinnie --- .../10-regexp-backreferences/article.md | 38 ++++++------- .../01-find-programming-language/solution.md | 18 +++---- .../01-find-programming-language/task.md | 6 +-- .../02-find-matching-bbtags/solution.md | 10 ++-- .../02-find-matching-bbtags/task.md | 20 +++---- .../03-match-quoted-string/solution.md | 14 ++--- .../03-match-quoted-string/task.md | 16 +++--- .../04-match-exact-tag/solution.md | 10 ++-- .../04-match-exact-tag/task.md | 8 +-- .../11-regexp-alternation/article.md | 53 ++++++++++--------- 10 files changed, 97 insertions(+), 96 deletions(-) diff --git a/5-regular-expressions/10-regexp-backreferences/article.md b/5-regular-expressions/10-regexp-backreferences/article.md index a5d251078b..dbecf420ff 100644 --- a/5-regular-expressions/10-regexp-backreferences/article.md +++ b/5-regular-expressions/10-regexp-backreferences/article.md @@ -1,12 +1,12 @@ -# Backreferences: \n and $n +# 反向引用:\n 和 $n -Capturing groups may be accessed not only in the result, but in the replacement string, and in the pattern too. +捕获组不仅能在结果中读取,也能在替换字符换,甚至模式中读取。 -## Group in replacement: $n +## 替换字符串中的组:$n -When we are using `replace` method, we can access n-th group in the replacement string using `$n`. +`replace` 方法中可以用 `$n` 在替换字符串中访问第 n 个捕获组。 -For instance: +例如: ```js run let name = "John Smith"; @@ -15,19 +15,19 @@ name = name.replace(/(\w+) (\w+)/i, *!*"$2, $1"*/!*); alert( name ); // Smith, John ``` -Here `pattern:$1` in the replacement string means "substitute the content of the first group here", and `pattern:$2` means "substitute the second group here". +这里替换字符串中的 `pattern:$1` 的意思是“在这里替换第一个捕获组的内容”,`pattern:$2` 的意思是“在这里替换第二个捕获组的内容”。 -Referencing a group in the replacement string allows us to reuse the existing text during the replacement. +在替换字符串中引用组允许我们在替换时重用已存在的文本。 -## Group in pattern: \n +## 模式中的组:\n -A group can be referenced in the pattern using `\n`. +在模式中,可以用 `\n` 引用组。 -To make things clear let's consider a task. We need to find a quoted string: either a single-quoted `subject:'...'` or a double-quoted `subject:"..."` -- both variants need to match. +为了更好的说明,假设有一个任务。我们需要找出引号:要么是单引号 `subject:'...'`,要么是双引号 `subject:"..."` —— 这两种类型都要找出来。 -How to look for them? +怎么查找这类引用组呢? -We can put two kinds of quotes in the pattern: `pattern:['"](.*?)['"]`. That finds strings like `match:"..."` and `match:'...'`, but it gives incorrect matches when one quote appears inside another one, like the string `subject:"She's the one!"`: +模式里要有两种引号:`pattern:['"](.*?)['"]`。匹配形如 `match:"..."` 和 `match:'...'` 的字符串,但当两类符号存在嵌套是,结果就不正确了,例如字符串 `subject:"She's the one!"`: ```js run let str = "He said: \"She's the one!\"."; @@ -38,9 +38,9 @@ let reg = /['"](.*?)['"]/g; alert( str.match(reg) ); // "She' ``` -As we can see, the pattern found an opening quote `match:"`, then the text is consumed lazily till the other quote `match:'`, that closes the match. +如你所见,这个模式发现了左双引号 `match:"`,然后文本全部匹配直到另一个引号 `match:'` 匹配,结束本次匹配。 -To make sure that the pattern looks for the closing quote exactly the same as the opening one, let's make a group of it and use the backreference: +为了确保模式匹配的右引号类型和左引号类型一致,可以将引号包裹成组并使用反向引用: ```js run let str = "He said: \"She's the one!\"."; @@ -50,11 +50,11 @@ let reg = /(['"])(.*?)\1/g; alert( str.match(reg) ); // "She's the one!" ``` -Now everything's correct! The regular expression engine finds the first quote `pattern:(['"])` and remembers the content of `pattern:(...)`, that's the first capturing group. +现在一切搞定!正则表达式引擎匹配第一个引号 `pattern:(['"])` 时,记录 `pattern(...)` 的内容,这就是第一个捕获组。 -Further in the pattern `pattern:\1` means "find the same text as in the first group". +`pattern:\1` 的含义是“找到与第一组相同的文本”。 -Please note: +请注意: -- To reference a group inside a replacement string -- we use `$1`, while in the pattern -- a backslash `\1`. -- If we use `?:` in the group, then we can't reference it. Groups that are excluded from capturing `(?:...)` are not remembered by the engine. +- 在替换字符串内部引用组的方式 —— `$1`,在模式中引用组的方式 —— `\1`。 +- 组内标记 `?:` 则无法引用到该组。正则表达式引擎不会记忆用 `(?:...)` 标记的捕获组。 diff --git a/5-regular-expressions/11-regexp-alternation/01-find-programming-language/solution.md b/5-regular-expressions/11-regexp-alternation/01-find-programming-language/solution.md index 3419aa4989..cad8534746 100644 --- a/5-regular-expressions/11-regexp-alternation/01-find-programming-language/solution.md +++ b/5-regular-expressions/11-regexp-alternation/01-find-programming-language/solution.md @@ -1,7 +1,7 @@ -The first idea can be to list the languages with `|` in-between. +第一个解法是列出所有语言,中间加上 `|` 符号。 -But that doesn't work right: +但是运行不如所愿: ```js run let reg = /Java|JavaScript|PHP|C|C\+\+/g; @@ -11,18 +11,18 @@ let str = "Java, JavaScript, PHP, C, C++"; alert( str.match(reg) ); // Java,Java,PHP,C,C ``` -The regular expression engine looks for alternations one-by-one. That is: first it checks if we have `match:Java`, otherwise -- looks for `match:JavaScript` and so on. +正则表达式引擎查找选择模式的时是挨个查找的。意思是:它先匹配是否存在 `match:Java`,否则 —— 接着匹配 `match:JavaScript` 及其后的字符串。 -As a result, `match:JavaScript` can never be found, just because `match:Java` is checked first. +结果,`match:JavaScript` 永远匹配不到,因为 `match:Java` 先被匹配了。 -The same with `match:C` and `match:C++`. +`match:C` 和 `match:C++` 同理。 -There are two solutions for that problem: +这个问题有两个解决办法: -1. Change the order to check the longer match first: `pattern:JavaScript|Java|C\+\+|C|PHP`. -2. Merge variants with the same start: `pattern:Java(Script)?|C(\+\+)?|PHP`. +1. 变更匹配顺序,长的字符串优先匹配:`pattern:JavaScript|Java|C\+\+|C|PHP`。 +2. 合并相同前缀:`pattern:Java(Script)?|C(\+\+)?|PHP`。 -In action: +运行代码如下: ```js run let reg = /Java(Script)?|C(\+\+)?|PHP/g; diff --git a/5-regular-expressions/11-regexp-alternation/01-find-programming-language/task.md b/5-regular-expressions/11-regexp-alternation/01-find-programming-language/task.md index 61b9526f78..6d04da822d 100644 --- a/5-regular-expressions/11-regexp-alternation/01-find-programming-language/task.md +++ b/5-regular-expressions/11-regexp-alternation/01-find-programming-language/task.md @@ -1,8 +1,8 @@ -# Find programming languages +# 查找编程语言 -There are many programming languages, for instance Java, JavaScript, PHP, C, C++. +有许多编程语言,例如 Java, JavaScript, PHP, C, C++。 -Create a regexp that finds them in the string `subject:Java JavaScript PHP C++ C`: +构建一个正则式,用以在字符串 `subject:Java JavaScript PHP C++ C` 中把他们匹配出来: ```js let reg = /your regexp/g; diff --git a/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/solution.md b/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/solution.md index 03080f86c1..cf8d0b0019 100644 --- a/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/solution.md +++ b/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/solution.md @@ -1,11 +1,11 @@ -Opening tag is `pattern:\[(b|url|quote)\]`. +起始标签是 `pattern:\[(b|url|quote)\]`。 -Then to find everything till the closing tag -- let's the pattern `pattern:[\s\S]*?` to match any character including the newline and then a backreference to the closing tag. +匹配字符串直到遇到结束标签 —— 模式 `pattern:[\s\S]*?` 匹配任意字符,包括换行和用于结束标记的反向引用。 -The full pattern: `pattern:\[(b|url|quote)\][\s\S]*?\[/\1\]`. +完整模式为:`pattern:\[(b|url|quote)\][\s\S]*?\[/\1\]`。 -In action: +运行代码如下: ```js run let reg = /\[(b|url|quote)\][\s\S]*?\[\/\1\]/g; @@ -20,4 +20,4 @@ let str = ` alert( str.match(reg) ); // [b]hello![/b],[quote][url]http://google.com[/url][/quote] ``` -Please note that we had to escape a slash for the closing tag `pattern:[/\1]`, because normally the slash closes the pattern. +请注意结束标签的转义反斜杠,通常斜杠会关闭模式。 diff --git a/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/task.md b/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/task.md index e0919e0348..51ec2d7e6a 100644 --- a/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/task.md +++ b/5-regular-expressions/11-regexp-alternation/02-find-matching-bbtags/task.md @@ -1,25 +1,25 @@ -# Find bbtag pairs +# 查找 bbtag 对 -A "bb-tag" looks like `[tag]...[/tag]`, where `tag` is one of: `b`, `url` or `quote`. +“bb-tag” 形如 `[tag]...[/tag]`,`tag` 匹配 `b`、`url` 或 `quote` 其中之一。 -For instance: +例如: ``` [b]text[/b] [url]http://google.com[/url] ``` -BB-tags can be nested. But a tag can't be nested into itself, for instance: +BB-tags 可以嵌套。但标签不能自嵌套,比如: ``` -Normal: +可行: [url] [b]http://google.com[/b] [/url] [quote] [b]text[/b] [/quote] -Impossible: +不可行: [b][b]text[/b][/b] ``` -Tags can contain line breaks, that's normal: +标签可以包含换行,通常为以下形式: ``` [quote] @@ -27,9 +27,9 @@ Tags can contain line breaks, that's normal: [/quote] ``` -Create a regexp to find all BB-tags with their contents. +构造一个正则式用于查找所有 BB-tags 和其内容。 -For instance: +举例: ```js let reg = /your regexp/g; @@ -38,7 +38,7 @@ let str = "..[url]http://google.com[/url].."; alert( str.match(reg) ); // [url]http://google.com[/url] ``` -If tags are nested, then we need the outer tag (if we want we can continue the search in its content): +如果标签嵌套,那么我们需要记录匹配的外层标签(如果希望继续查找匹配的标签内容的话): ```js let reg = /your regexp/g; diff --git a/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/solution.md b/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/solution.md index 143be870c7..3d80404920 100644 --- a/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/solution.md +++ b/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/solution.md @@ -1,13 +1,13 @@ -The solution: `pattern:/"(\\.|[^"\\])*"/g`. +答案是 `pattern:/"(\\.|[^"\\])*"/g`。 -Step by step: +步骤如下: -- First we look for an opening quote `pattern:"` -- Then if we have a backslash `pattern:\\` (we technically have to double it in the pattern, because it is a special character, so that's a single backslash in fact), then any character is fine after it (a dot). -- Otherwise we take any character except a quote (that would mean the end of the string) and a backslash (to prevent lonely backslashes, the backslash is only used with some other symbol after it): `pattern:[^"\\]` -- ...And so on till the closing quote. +- 首先匹配左双引号 `pattern:"` +- 接着如果有反斜杠 `pattern:\\`,则匹配其后跟随的任意字符。(技术上,我们必须在模式中用双反斜杠,因为它是一个特殊的字符,但实际上是一个反斜杠字符) +- 如果没有,则匹配除双引号(字符串的结束)和反斜杠(排除仅存在反斜杠的情况,反斜杠仅在和其后字符一起使用时有效)外的任意字符:`pattern:[^"\\]` +- ......继续匹配直到遇到反双引号 -In action: +运行代码如下: ```js run let reg = /"(\\.|[^"\\])*"/g; diff --git a/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/task.md b/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/task.md index 2ccac4bdfa..4c14ade87a 100644 --- a/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/task.md +++ b/5-regular-expressions/11-regexp-alternation/03-match-quoted-string/task.md @@ -1,20 +1,20 @@ -# Find quoted strings +# 查询引用字符串 -Create a regexp to find strings in double quotes `subject:"..."`. +构建一个正则表达式用于匹配双引号内的字符串 `subject:"..."`。 -The important part is that strings should support escaping, in the same way as JavaScript strings do. For instance, quotes can be inserted as `subject:\"` a newline as `subject:\n`, and the slash itself as `subject:\\`. +最重要的部分是字符串应该支持转义,正如 JavaScript 字符串的行为一样。例如,引号可以插入为 `subject:\`,换行符为 `subject:\n`,斜杠本身为 `subject:\`。 ```js let str = "Just like \"here\"."; ``` -For us it's important that an escaped quote `subject:\"` does not end a string. +对我们来说,重要的是转义的引号 `subject:\` 不会结束字符串匹配。 -So we should look from one quote to the other ignoring escaped quotes on the way. +所以,我们应该匹配两个引号之间的内容,且忽略中间转义的引号。 -That's the essential part of the task, otherwise it would be trivial. +这是任务的关键部分,否则这个任务就没什么意思了。 -Examples of strings to match: +匹配字符串示例: ```js .. *!*"test me"*/!* .. .. *!*"Say \"Hello\"!"*/!* ... (escaped quotes inside) @@ -22,7 +22,7 @@ Examples of strings to match: .. *!*"\\ \""*/!* .. (double slash and an escaped quote inside) ``` -In JavaScript we need to double the slashes to pass them right into the string, like this: +在 JavaScript 中,双斜杠用于把斜杠转义为字符串,如下所示: ```js run let str = ' .. "test me" .. "Say \\"Hello\\"!" .. "\\\\ \\"" .. '; diff --git a/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/solution.md b/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/solution.md index 70c4de91ab..8de841646f 100644 --- a/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/solution.md +++ b/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/solution.md @@ -1,13 +1,13 @@ -The pattern start is obvious: `pattern:`, because `match:` would match it. +......然而接着不能简单地写出 `pattern:` 这样的表达式,因为会同时匹配 `match:`。 -We need either a space after `match:`. +要么匹配 `match:`。 -In the regexp language: `pattern:|\s.*?>)`. +最终的正则表达式为:`pattern:|\s.*?>)`。 -In action: +运行代码如下: ```js run let reg = /|\s.*?>)/g; diff --git a/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/task.md b/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/task.md index 85976a9e7b..f69b9ccc8c 100644 --- a/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/task.md +++ b/5-regular-expressions/11-regexp-alternation/04-match-exact-tag/task.md @@ -1,10 +1,10 @@ -# Find the full tag +# 查找完整标签 -Write a regexp to find the tag ``. It should match the full tag: it may have no attributes `