aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/guide/regular_expressions
diff options
context:
space:
mode:
Diffstat (limited to 'files/zh-cn/web/javascript/guide/regular_expressions')
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html263
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html6
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html216
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html164
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/index.html745
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html171
-rw-r--r--files/zh-cn/web/javascript/guide/regular_expressions/量词/index.html170
7 files changed, 1735 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html
new file mode 100644
index 0000000000..a9ef01776b
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/assertions/index.html
@@ -0,0 +1,263 @@
+---
+title: Assertions
+slug: Web/JavaScript/Guide/Regular_Expressions/Assertions
+tags:
+ - JavaScript
+ - 参考
+ - 指南
+ - 正则
+ - 正则表达式
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions
+---
+<p>{{jsSidebar("JavaScript Guide")}}</p>
+
+<p>断言的组成之一是边界。对于文本、词或模式,边界可以用来表明它们的起始或终止部分(如向前断言,向后断言以及条件表达式)。</p>
+
+<p>{{EmbedInteractiveExample("pages/js/regexp-assertions.html", "taller")}}</p>
+
+<h2 id="类型">类型</h2>
+
+<h3 id="边界类断言">边界类断言</h3>
+
+<table>
+ <thead>
+ <tr>
+ <th scope="col">字符</th>
+ <th scope="col">含义</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code>^</code></td>
+ <td>
+ <p>匹配输入的开头。如果多行模式设为 true,<code>^</code> 在换行符后也能立即匹配,比如 <code>/^A/</code> 匹配不了 "an A" 里面的 "A",但是可以匹配 "An A" 里面第一个 "A"。</p>
+
+ <div class="blockIndicator note">
+ <p><code>^</code> 出现在集合或范围开头时的含义与此不同(参见 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">group</a>)。</p>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>$</code></td>
+ <td>
+ <p>匹配输入的结束。如果多行模式设为 true,<code>^</code> 在换行符前也能立即匹配,比如 <code>/t$/</code> 不能匹配  "eater" 中的 "t",但是可以匹配 "eat" 中的 "t"。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\b</code></td>
+ <td>
+ <p>匹配一个单词的边界,这是一个字的字符前后没有另一个字的字符位置, 例如在字母和空格之间。需要注意的是匹配的单词边界不包括在匹配中。换句话说,匹配字边界的长度为零。</p>
+
+ <p>一些例子:</p>
+
+ <ul>
+ <li><code>/\bm/</code>  在 "moon" 中匹配到 "m" </li>
+ <li><code>/oo\b/</code>  在 "moon" 中不会匹配到 "oo", 因为 "oo" 后面跟着 "n" 这个单词字符.</li>
+ <li><code>/oon\b/</code> 在 "moon" 中匹配 "oon", 因为 "oon" 是这个字符串的结尾, 因此后面没有单词字符</li>
+ <li><code>/\w\b\w/</code> 将永远不会匹配任何东西,因为一个单词字符后面永远不会有非单词字符和单词字符。</li>
+ </ul>
+
+ <p>匹配退格字符 (<code>[\b]</code>), 查看 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类</a> </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\B</code></td>
+ <td>
+ <p>匹配非单词边界。这是上一个字符和下一个字符属于同一类型的位置:要么两者都必须是单词,要么两者都必须是非单词,例如在两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的词边界相同,匹配的非词边界也不包含在匹配中。例如,<code>/\Bon/</code> 在 “at noon” 中匹配 “on” ,<code>/ye\B/</code> 在 "possibly yesterday"中匹配"ye" 。</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="其他断言">其他断言 </h3>
+
+<div class="blockIndicator note">
+<p>提示:<code>?</code>字符也可用作量词</p>
+</div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col"><code>字符</code></th>
+ <th scope="col"><code>含义</code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <p><code>x(?=y)</code>                </p>
+ </td>
+ <td>
+ <table>
+ <tbody>
+ <tr>
+ <td><strong>向前断言:</strong> x 被 y 跟随时匹配 x。例如,对于/<code>Jack(?=Sprat)</code>/,“Jack”在跟有“Sprat”的情况下才会得到匹配.<code>/Jack(?=Sprat|Frost)/</code> “Jack”后跟有“Sprat”或“Frost”的情况下才会得到匹配。不过, 匹配结果不包括“Sprat”或“Frost”。</td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>x(?!y)</td>
+ <td>
+ <table>
+ <tbody>
+ <tr>
+ <td><strong>向前否定断言:</strong> x 没有被 y 紧随时匹配 x。例如,对于<code>/\d+(?!\。)/</code>,数字后没有跟随小数点的情况下才会得到匹配。对于<code>/\d+(?!\.)/.exec(3.141)</code>,匹配‘141’而不是‘3’。</td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>(?&lt;=y)x</td>
+ <td>
+ <table>
+ <tbody>
+ <tr>
+ <td><strong>向后断言:</strong> x 跟随 y 的情况下匹配 x。例如,对于<code>/(?&lt;=Jack)Sprat/</code>,“Sprat”紧随“Jack”时才会得到匹配。对于<code>/(?&lt;=Jack|Tom)Sprat</code>,“Sprat”在紧随“Jack”或“Tom”的情况下才会得到匹配。不过,匹配结果中不包括“Jack”或“Tom”。</td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <td>(?&lt;!y)x</td>
+ <td>
+ <table>
+ <tbody>
+ <tr>
+ <td><strong>向后否定断言:</strong> x 不跟随 y 时匹配 x。例如,对于<code>/(?&lt;!-)\d+/</code>,数字不紧随-符号的情况下才会得到匹配。对于<code>/(?&lt;!-)\d+/.exec(3)</code> ,“3”得到匹配。 而<code>/(?&lt;!-)\d+/.exec(-3)</code>的结果无匹配,这是由于数字之前有-符号。</td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="示例">示例</h2>
+
+<h3 id="一般边界类型概述示例">一般边界类型概述示例</h3>
+
+<pre class="notranslate">// 使用 正则表达式边界修复错误字符串
+buggyMultiline = `tey, ihe light-greon apple
+tangs on ihe greon traa`;
+
+// 1) 使用 ^ 修正字符串开始处和换行后的匹配.
+buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
+console.log(1, buggyMultiline); // 修复 'tey'=&gt;'hey'(字符串开始) , 'tangs'=&gt;'hangs'(换行后)
+
+// 2) 使用 $ 修正字符串结尾处的匹配.
+buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
+console.log(2, buggyMultiline); // 修复 'traa' =&gt; 'tree'.
+
+// 3) 使用 \b 修正单词和空格边界上的字符.
+buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
+console.log(3, buggyMultiline); // 修复 'ihe' =&gt; 'the' 不影响 'light'.
+
+// 4) 使用 \B 匹配实体边界内的字符.
+fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
+console.log(4, fixedMultiline); // 修复 'greon' 不影响'on'.</pre>
+
+<h3 id="使用_(控制字符)匹配输入的开头">使用 ^(控制字符)匹配输入的开头</h3>
+
+<p>使用 <code>^</code>匹配输入的开头。在这个例子中,我们可以通过 /^A/ 正则表达式得到以A开头的水果。为了选择合适的水果,我们可以使用带有箭头函数的过滤方法.</p>
+
+<pre class="notranslate">let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// 使用正则 /^A/ 选择以'A'开头的水果.
+// 这里的 '^' 只有一种含义: 匹配输入的开头.
+
+let fruitsStartsWithA = fruits.filter(fruit =&gt; /^A/.test(fruit));
+console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]</pre>
+
+<p>在第二个示例中,^用于在输入的开始处匹配,以及在内部使用时用于创建否定或被补充的字符集 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">组和范围</a>.</p>
+
+<pre class="notranslate">let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// 使用正则 /^[^A]/ 选择 不是以 ‘A’ 开头的水果
+// 在这个例子中,“^” 控件符号表示两种含义:
+// 1) 匹配输入的开头
+// 2) 一个否定的字符集: [^A] ,意思是匹配不是 ‘A’ 的字符
+
+let fruitsStartsWithNotA = fruits.filter(fruit =&gt; /^[^A]/.test(fruit));
+
+console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]</pre>
+
+<h3 id="匹配字边界">匹配字边界</h3>
+
+<pre class="notranslate">let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
+
+// 选择包含以 “en” 或 “ed” 结尾的单词的描述:
+let enEdSelection = fruitsWithDescription.filter(descr =&gt; /(en|ed)\b/.test(descr));
+
+console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]</pre>
+
+<h3 id="向前断言">向前断言</h3>
+
+<pre class="notranslate">// JS 向前断言 x(?=y) 匹配被 y 跟随的 x
+
+let regex = /First(?= test)/g;
+
+console.log('First test'.match(regex)); // [ 'First' ]
+console.log('test First peach'.match(regex)); // null
+console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
+console.log('This is a First peach in a month.'.match(regex)); // null</pre>
+
+<h3 id="向前否定断言">向前否定断言</h3>
+
+<p>例如, <code>/\d+(?!\.)/</code> 匹配没有被小数点跟随且至少有一位的数字。 <code>/\d+(?!\.)/.exec('3.141')</code> 匹配 "141" 而不是 "3" </p>
+
+<pre class="notranslate">console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]</pre>
+
+<h3 id="不同含义的!:断言和范围的组合用法">不同含义的'?!':断言和范围的组合用法</h3>
+
+<p>不同含义的<code>?!</code> 结合使用 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">断言</a>  <code>/x(?!y)/ </code>和  <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">范围</a> <code>[^?!]</code>.</p>
+
+<pre class="notranslate">let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
+
+let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
+
+let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]</pre>
+
+<h3 id="向后断言">向后断言</h3>
+
+<pre class="notranslate">let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
+
+let ripe_oranges = oranges.filter( fruit =&gt; fruit.match(/(?&lt;=ripe )orange/));
+console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]</pre>
+
+<h2 id="规范">规范</h2>
+
+<table>
+ <tbody>
+ <tr>
+ <th scope="col">详述</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="浏览器_兼容性">浏览器 兼容性</h2>
+
+<p>有关浏览器兼容性的信息,请查看 <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">main Regular Expressions compatibility table</a>.</p>
+
+<h2 id="另请参阅">另请参阅</h2>
+
+<ul>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">正则表达式指南</a>
+
+ <ul>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">量词</a> </li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode 属性转义</a></li>
+ <li><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">组和范围</a></li>
+ </ul>
+ </li>
+ <li> <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">RegExp() 构造器</a></li>
+</ul>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html
new file mode 100644
index 0000000000..0c5b2f4eb9
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html
@@ -0,0 +1,6 @@
+---
+title: Boundaries
+slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions
+---
+<p>重定向至 <a class="redirect" href="/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">断言</a></p>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html
new file mode 100644
index 0000000000..26b1f4ee4a
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/character_classes/index.html
@@ -0,0 +1,216 @@
+---
+title: 字符类
+slug: Web/JavaScript/Guide/Regular_Expressions/Character_Classes
+tags:
+ - 字符类
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Character_Classes
+---
+<p>{{JSSidebar("JavaScript Guide")}}</p>
+
+<p>字符类可以区分各种字符,例如区分字母和数字。</p>
+
+<div>{{EmbedInteractiveExample("pages/js/regexp-character-classes.html")}}</div>
+
+<h2 id="类型">类型</h2>
+
+<div class="hidden">The following table is also duplicated on <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">this cheatsheet</a>. Do not forget to edit it as well, thanks!</div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Characters</th>
+ <th scope="col">Meaning</th>
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+ <tbody>
+ <tr>
+ <td><code>.</code></td>
+ <td>
+ <p>有下列含义之一:</p>
+
+ <ul>
+ <li>匹配除行终止符之外的任何单个字符: <code>\n</code>, <code>\r</code>, <code>\u2028</code> or <code>\u2029</code>. 例如, <code>/.y/</code> 在“yes make my day”中匹配“my”和“ay”,而不是“yes”。</li>
+ <li>在字符集内,点失去了它的特殊意义,并与文字点匹配。</li>
+ </ul>
+
+ <p>需要注意的是,<code>m</code> multiline标志不会改变点的行为。因此,要跨多行匹配一个模式,可以使用字符集<code>[^]</code>—它将匹配任何字符,包括新行。</p>
+
+ <p>ES2018 添加了 <code>s</code> "dotAll" 标志,它允许点也匹配行终止符。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\d</code></td>
+ <td>
+ <p>匹配任何数字(阿拉伯数字)。 相当于 <code>[0-9]</code>. 例如, <code>/\d/</code> 或 <code>/[0-9]/</code> 匹配 “B2is the suite number”中的“2”。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\D</code></td>
+ <td>
+ <p>匹配任何非数字(阿拉伯数字)的字符。相当于<code>[^0-9]</code>. 例如, <code>/\D/</code> or <code>/[^0-9]/</code> 在 "B2 is the suite number" 中 匹配 "B".</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\w</code></td>
+ <td>
+ <p>匹配基本拉丁字母中的任何字母数字字符,包括下划线。相当于 <code>[A-Za-z0-9_]</code>. 例如, <code>/\w/</code> 在 "apple" 匹配 "a" , "5" in "$5.28", "3" in "3D" and "m" in "Émanuel".</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\W</code></td>
+ <td>
+ <p>匹配任何不是来自基本拉丁字母的单词字符。相当于 <code>[^A-Za-z0-9_]</code>. 例如, <code>/\W/</code> or <code>/[^A-Za-z0-9_]/</code> 匹配 "%" 在 "50%" 以及 "É" 在 "Émanuel" 中.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\s</code></td>
+ <td>
+ <p>Matches a single white space character, including space, tab, form feed, line feed, and other Unicode spaces. Equivalent to <code>[ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code>. For example, <code>/\s\w*/</code> matches " bar" in "foo bar".</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\S</code></td>
+ <td>
+ <p>Matches a single character other than white space. Equivalent to <code>[^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code>. For example, <code>/\S\w*/</code> matches "foo" in "foo bar".</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\t</code></td>
+ <td>Matches a horizontal tab.</td>
+ </tr>
+ <tr>
+ <td><code>\r</code></td>
+ <td>Matches a carriage return.</td>
+ </tr>
+ <tr>
+ <td><code>\n</code></td>
+ <td>Matches a linefeed.</td>
+ </tr>
+ <tr>
+ <td><code>\v</code></td>
+ <td>Matches a vertical tab.</td>
+ </tr>
+ <tr>
+ <td><code>\f</code></td>
+ <td>Matches a form-feed.</td>
+ </tr>
+ <tr>
+ <td><code>[\b]</code></td>
+ <td>Matches a backspace. If you're looking for the word-boundary character (<code>\b</code>), see <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries">Boundaries</a>.</td>
+ </tr>
+ <tr>
+ <td><code>\0</code></td>
+ <td>Matches a NUL character. Do not follow this with another digit.</td>
+ </tr>
+ <tr>
+ <td><code>\c<em>X</em></code></td>
+ <td>
+ <p>Matches a control character using <a href="https://en.wikipedia.org/wiki/Caret_notation">caret notation</a>, where "X" is a letter from A–Z (corresponding to codepoints <code>U+0001</code><em>–</em><code>U+001F</code>). For example, <code>/\cM/</code> matches "\r" in "\r\n".</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\x<em>hh</em></code></td>
+ <td>Matches the character with the code <code><em>hh</em></code> (two hexadecimal digits).</td>
+ </tr>
+ <tr>
+ <td><code>\u<em>hhhh</em></code></td>
+ <td>Matches a UTF-16 code-unit with the value <code><em>hhhh</em></code> (four hexadecimal digits).</td>
+ </tr>
+ <tr>
+ <td><code>\u<em>{hhhh} </em>or <em>\u{hhhhh}</em></code></td>
+ <td>(Only when the <code>u</code> flag is set.) Matches the character with the Unicode value <code>U+<em>hhhh</em></code> or <code>U+<em>hhhhh</em></code> (hexadecimal digits).</td>
+ </tr>
+ <tr>
+ <td><code>\</code></td>
+ <td>
+ <p>Indicates that the following character should be treated specially, or "escaped". It behaves one of two ways.</p>
+
+ <ul>
+ <li>For characters that are usually treated literally, indicates that the next character is special and not to be interpreted literally. For example, <code>/b/</code> matches the character "b". By placing a backslash in front of "b", that is by using <code>/\b/</code>, the character becomes special to mean match a word boundary.</li>
+ <li>For characters that are usually treated specially, indicates that the next character is not special and should be interpreted literally. For example, "*" is a special character that means 0 or more occurrences of the preceding character should be matched; for example, <code>/a*/</code> means match 0 or more "a"s. To match <code>*</code> literally, precede it with a backslash; for example, <code>/a\*/</code> matches "a*".</li>
+ </ul>
+
+ <div class="blockIndicator note">
+ <p>To match this character literally, escape it with itself. In other words to search for <code>\</code> use <code>/\\/</code>.</p>
+ </div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Examples">Examples</h2>
+
+<h3 id="Looking_for_a_series_of_digits">Looking for a series of digits</h3>
+
+<pre class="brush: js notranslate">var randomData = "015 354 8787 687351 3512 8735";
+var regexpFourDigits = /\b\d{4}\b/g;
+// \b indicates a boundary (i.e. do not start matching in the middle of a word)
+// \d{4} indicates a digit, four times
+// \b indicates another boundary (i.e. do not end matching in the middle of a word)
+
+
+console.table(randomData.match(regexpFourDigits));
+// ['8787', '3512', '8735']
+</pre>
+
+<h3 id="Looking_for_a_word_from_the_latin_alphabet_starting_with_A">Looking for a word (from the latin alphabet) starting with A</h3>
+
+<pre class="brush: js notranslate">var aliceExcerpt = "I’m sure I’m not Ada,’ she said, ‘for her hair goes in such long ringlets, and mine doesn’t go in ringlets at all.";
+var regexpWordStartingWithA = /\b[aA]\w+/g;
+// \b indicates a boundary (i.e. do not start matching in the middle of a word)
+// [aA] indicates the letter a or A
+// \w+ indicates any character *from the latin alphabet*, multiple times
+
+console.table(aliceExcerpt.match(regexpWordStartingWithA));
+// ['Ada', 'and', 'at', 'all']
+</pre>
+
+<h3 id="Looking_for_a_word_from_Unicode_characters">Looking for a word (from Unicode characters)</h3>
+
+<p>Instead of the Latin alphabet, we can use a range of Unicode characters to identify a word (thus being able to deal with text in other languages like Russian or Arabic). The "Basic Multilingual Plane" of Unicode contains most of the characters used around the world and we can use character classes and ranges to match words written with those characters.</p>
+
+<pre class="brush: js notranslate">var nonEnglishText = "Приключения Алисы в Стране чудес";
+var regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
+// BMP goes through U+0000 to U+FFFF but space is U+0020
+
+console.table(nonEnglishText.match(regexpBMPWord));
+[ 'Приключения', 'Алисы', 'в', 'Стране', 'чудес' ]
+</pre>
+
+<div class="hidden">
+<p>Note for MDN editors: please do not try to add funny examples with emoji as those characters are not handled by the platform (Kuma).</p>
+</div>
+
+<h2 id="Specifications">Specifications</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Specification</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-characterclass', 'RegExp: Character classes')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browser_compatibility">Browser compatibility</h2>
+
+<p>For browser compatibility information, check out the <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">main Regular Expressions compatibility table</a>.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Regular expressions guide</a>
+
+ <ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">Assertions</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">Quantifiers</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode property escapes</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">Groups and ranges</a></li>
+ </ul>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">The <code>RegExp()</code> constructor</a></li>
+</ul>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html
new file mode 100644
index 0000000000..9a73c9b8ef
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/groups_and_ranges/index.html
@@ -0,0 +1,164 @@
+---
+title: Groups and ranges
+slug: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges
+---
+<p>{{jsSidebar("JavaScript Guide")}}</p>
+
+<p>组和范围表示表达式字符的 组和范围</p>
+
+<div>{{EmbedInteractiveExample("pages/js/regexp-groups-ranges.html")}}</div>
+
+<h2 id="类型">类型</h2>
+
+<div class="hidden">The following section is also duplicated on <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">this cheatsheet</a>. Do not forget to edit it as well, thanks!</div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">字符集</th>
+ <th scope="col">含义</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code><em>x</em>|<em>y</em></code></td>
+ <td>
+ <p>匹配 "x" 或 "y" 任意一个字符。例如, <code>/green|red/</code> 在 "green apple" 里匹配 "green",且在 "red apple" 里匹配 "red" 。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>[xyz]<br>
+ [a-c]</code></td>
+ <td>
+ <p>字符集。 匹配任何一个包含的字符。您可以使用连字符来指定字符范围,但如果连字符显示为方括号中的第一个或最后一个字符,则它将被视为作为普通字符包含在字符集中的文字连字符。也可以在字符集中包含字符类。</p>
+
+ <p>例如, <code>[abcd]</code> 是与<code>[a-d]</code>.一样的,它们会 在"brisket" 中匹配 "b",在 "chop" 中匹配 "c" .</p>
+
+ <p>例如, <code>[abcd-]</code> 和<code>[-abcd]</code> 将会在 "brisket" 匹配 "b" , 在 "chop" 匹配 "c" , 并且匹配 "non-profit" 中的 "-" (连字符)</p>
+
+ <p>例如, <code>[\w-]</code> 是字符集 \w 和 “-”(连字符)的并集,与这种写法一样: <code>[A-Za-z0-9_-]</code>.。他们都会 在 "brisket"中匹配 “b”,  在 "chop"中匹配 “c”, 在 "non-profit" 中匹配 "n"。</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code>[^xyz]<br>
+ [^a-c]</code></p>
+ </td>
+ <td>
+ <p>一个否定的或被补充的字符集。也就是说,它匹配任何没有包含在括号中的字符。可以通过使用连字符来指定字符范围,但是如果连字符作为方括号中的第一个或最后一个字符出现,那么它将被视为作为普通字符包含在字符集中。例如,[^abc]和[^a-c]一样。它们最初匹配“bacon”中的“o”和“chop”中的“h”。</p>
+
+ <div class="blockIndicator note">
+ <p> ^ 字符也可以表示   <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries">输入的起始</a></p>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>(<em>x</em>)</code></td>
+ <td>
+ <p><strong>捕获组: </strong>匹配x并记住匹配项。例如,/(foo)/匹配并记住“foo bar”中的“foo” </p>
+
+ <p>正则表达式可以有多个捕获组。结果,匹配通常在数组中捕获的组,该数组的成员与捕获组中左括号的顺序相同。这通常只是捕获组本身的顺序。当捕获组被嵌套时,这一点非常重要。使用结果元素的索引 (<code>[1], ..., [n]</code>) 或从预定义的 <code>RegExp</code> 对象的属性 (<code>$1, ..., $9</code>).</p>
+
+ <p>捕获组会带来性能损失。如果不需要收回匹配的子字符串,请选择非捕获括号(见下面)。</p>
+
+ <p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match">String.match()</a></code> 不会返回组,如果设置了 <code>/.../g</code> 标志. 但是,您仍然可以使用 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll">String.matchAll()</a></code> to get all matches.</p>
+
+ <p>match()不会返回组,如果/…但是,您仍然可以使用String.matchAll()来获取所有匹配项。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>\<em>n</em></code></td>
+ <td>
+ <p>其中n是一个正整数。对正则表达式中与n括号匹配的最后一个子字符串的反向引用(计算左括号)。例如,<code>/apple(,)\sorange\1/</code> 匹配 “apple,orange,cherry,peach” 中的 "apple,orange,", 其中 <code>\1</code> 引用了 之前使用 <code>()</code> 捕获的 <code>,</code></p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>(?&lt;Name&gt;x)</code></td>
+ <td>
+ <p><strong>具名捕获组: </strong>匹配"x"并将其存储在返回的匹配项的groups属性中,该属性位于<code>&lt;Name&gt;</code>指定的名称下。尖括号(<code>&lt;</code> 和 <code>&gt;</code>) 用于组名。</p>
+
+ <p>例如,使用正则 <code>/-(?&lt;customName&gt;\w)/</code> 匹配 “web-doc” 中的 “d”</p>
+
+ <p><code>'web-doc'.match(/-(?&lt;customName&gt;\w)/).groups   //{customName: "d"} </code>   </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>(?:<em>x</em>)</code></td>
+ <td><strong>非捕获组: </strong>匹配 “x”,但不记得匹配。不能从结果数组的元素中收回匹配的子字符串(<code>[1], ..., [n]</code>) or from the predefined <code>RegExp</code> object's properties (<code>$1, ..., $9</code>).</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="一些例子">一些例子</h2>
+
+<h3 id="计算元音数">计算元音数</h3>
+
+<pre class="brush: js notranslate">var aliceExcerpt = "There was a long silence after this, and Alice could only hear whispers now and then.";
+var regexpVowels = /[aeiouy]/g;
+
+console.log("Number of vowels:", aliceExcerpt.match(regexpVowels).length);
+// Number of vowels: 25</pre>
+
+<h3 id="使用_组">使用 组</h3>
+
+<pre class="brush: js notranslate">let personList = `First_Name: John, Last_Name: Doe
+First_Name: Jane, Last_Name: Smith`;
+
+let regexpNames =  /First_Name: (\w+), Last_Name: (\w+)/mg;
+let match = regexpNames.exec(personList);
+do {
+  console.log(`Hello ${match[1]} ${match[2]}`);
+} while((match = regexpNames.exec(personList)) !== null);
+</pre>
+
+<h3 id="使用命名组">使用命名组</h3>
+
+<pre class="brush: js notranslate">let users= `姓氏: 李, 名字: 雷
+姓氏: 韩, 名字: 梅梅`;
+
+let regexpNames = /姓氏: (?&lt;first&gt;.+), 名字: (?&lt;last&gt;.+)/mg;
+let match = regexpNames.exec(users);
+
+do {
+  console.log(`Hello ${match.groups.first} ${match.groups.last}`);
+} while((match = regexpNames.exec(users)) !== null);
+
+// Hellow 李 雷
+// Hellow 韩 梅梅</pre>
+
+<div class="blockIndicator note">
+<p><strong>Note:</strong> 并不是所有的浏览器都支持这个功能; 参考兼容表: <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">compatibility table</a>.</p>
+</div>
+
+<h2 id="技术指标">技术指标</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">技术指标</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-classranges', 'RegExp: Ranges')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="浏览器兼容性">浏览器兼容性</h2>
+
+<p>有关浏览器兼容性的信息,请查看 <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">main Regular Expressions compatibility table</a>.</p>
+
+<h2 id="另请参阅">另请参阅</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">正则表达式指南</a>
+
+ <ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">断言</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">量词</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode 属性转义</a></li>
+ </ul>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">正则构造函数</a></li>
+</ul>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/index.html
new file mode 100644
index 0000000000..4d88167c80
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/index.html
@@ -0,0 +1,745 @@
+---
+title: 正则表达式
+slug: Web/JavaScript/Guide/Regular_Expressions
+tags:
+ - JavaScript
+ - RegExp
+ - Regular Expressions
+ - 中级
+ - 参考
+ - 指南
+ - 正则表达式
+translation_of: Web/JavaScript/Guide/Regular_Expressions
+---
+<p>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</p>
+
+<p>正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象。这些模式被用于 {{jsxref("RegExp")}} 的 {{jsxref("RegExp.exec", "exec")}} 和 {{jsxref("RegExp.test", "test")}} 方法, 以及 {{jsxref("String")}} 的 {{jsxref("String.match", "match")}}、{{jsxref("String.matchAll", "matchAll")}}、{{jsxref("String.replace", "replace")}}、{{jsxref("String.search", "search")}} 和 {{jsxref("String.split", "split")}} 方法。本章介绍 JavaScript 正则表达式。</p>
+
+<h2 id="创建一个正则表达式">创建一个正则表达式</h2>
+
+<p>你可以使用以下两种方法构建一个正则表达式:</p>
+
+<p>使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示:</p>
+
+<pre class="brush: js notranslate">var re = /ab+c/;
+</pre>
+
+<p>脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。</p>
+
+<p>或者调用<code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp" title="zh-CN/docs/JavaScript/Reference/Global Objects/RegExp">RegExp</a></code>对象的构造函数,如下所示:</p>
+
+<pre class="brush: js notranslate">var re = new RegExp("ab+c");
+</pre>
+
+<p>在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。</p>
+
+<h2 id="编写一个正则表达式的模式">编写一个正则表达式的模式</h2>
+
+<p>一个正则表达式模式是由简单的字符所构成的,比如 <code>/abc/</code>;或者是简单和特殊字符的组合,比如 <code>/ab*c/</code> 或 <code>/Chapter (\d+)\.\d*/</code>。最后的例子中用到了括号,它在正则表达式中常用作记忆设备。即这部分所匹配的字符将会被记住以备后续使用,例如<a href="#使用括号的子字符串匹配">使用括号的子字符串匹配</a>。</p>
+
+<h3 id="使用简单模式">使用简单模式</h3>
+
+<p>简单模式是由你想直接找到的字符构成。比如,<code>/abc/</code> 这个模式就能且仅能匹配 "abc" 字符按照顺序同时出现的情况。例如在 "Hi, do you know your abc's?" 和 "The latest airplane designs evolved from slabcraft." 中会匹配成功。在上述两个例子中,匹配的子字符串是 "abc"。但是在 "Grab crab" 中会匹配失败,因为它虽然包含子字符串 "ab c",但并不是准确的 "abc"。</p>
+
+<h3 id="使用特殊字符">使用特殊字符</h3>
+
+<p>当你需要匹配一个不确定的字符串时,比如寻找一个或多个 "b",或者寻找空格,可以在模式中使用特殊字符。比如,你可以使用 <code>/ab*c/</code> 去匹配一个单独的 "a" 后面跟了零个或者多个 "b",同时后面跟着 "c" 的字符串:<code>*</code>的意思是前一项出现零次或者多次。在字符串 "cbbabbbbcdebc" 中,这个模式匹配了子字符串 "abbbbc"。</p>
+
+<p>下面的页面与表格列出了一个正则表达式中可以利用的特殊字符的完整列表和描述。</p>
+
+<dl>
+ <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">断言(Assertions)</a></dt>
+ <dd>表示一个匹配在某些条件下发生。断言包含先行断言、后行断言和条件表达式。</dd>
+ <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类(Character Classes)</a></dt>
+ <dd>区分不同类型的字符,例如区分字母和数字。</dd>
+ <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">组和范围(Groups and Ranges)</a></dt>
+ <dd>表示表达式字符的分组和范围。</dd>
+ <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">量词(Quantifiers)</a></dt>
+ <dd>表示匹配的字符或表达式的数量。</dd>
+ <dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode 属性转义(Unicode Property Escapes)</a></dt>
+ <dd>基于 unicode 字符属性区分字符。例如大写和小写字母、数学符号和标点。</dd>
+</dl>
+
+<table class="standard-table">
+ <caption>正则表达式中的特殊字符</caption>
+ <thead>
+ <tr>
+ <th scope="col">字符</th>
+ <th scope="col">含义</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><a href="#special-backslash" id="special-backslash" name="special-backslash"><code>\</code></a></td>
+ <td>
+ <p>依照下列规则匹配:</p>
+
+ <p>在非特殊字符之前的反斜杠表示下一个字符是特殊字符,不能按照字面理解。例如,前面没有 "\" 的 "b" 通常匹配小写字母 "b",即字符会被作为字面理解,无论它出现在哪里。但如果前面加了 "\",它将不再匹配任何字符,而是表示一个<a href="#note" title="#special-word-boundary">字符边界</a>。</p>
+
+ <p>在特殊字符之前的反斜杠表示下一个字符不是特殊字符,应该按照字面理解。详情请参阅下文中的 "转义(Escaping)" 部分。</p>
+
+ <p>如果你想将字符串传递给 RegExp 构造函数,不要忘记在字符串字面量中反斜杠是转义字符。所以为了在模式中添加一个反斜杠,你需要在字符串字面量中转义它。<code>/[a-z]\s/i</code> 和 <code>new RegExp("[a-z]\\s", "i")</code> 创建了相同的正则表达式:一个用于搜索后面紧跟着空白字符(<code>\s</code> 可看后文)并且在 a-z 范围内的任意字符的表达式。为了通过字符串字面量给 RegExp 构造函数创建包含反斜杠的表达式,你需要在字符串级别和正则表达式级别都对它进行转义。例如 <code>/[a-z]:\\/i</code> 和 <code>new RegExp("[a-z]:\\\\","i")</code> 会创建相同的表达式,即匹配类似 "C:\" 字符串。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-caret" id="special-caret" name="special-caret"><code>^</code></a></td>
+ <td>
+ <p>匹配输入的开始。如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。</p>
+
+ <p>例如,<code>/^A/</code> 并不会匹配 "an A" 中的 'A',但是会匹配 "An E" 中的 'A'。</p>
+
+ <p>当 '<code>^</code>' 作为第一个字符出现在一个字符集合模式时,它将会有不同的含义。<a href="#special-negated-character-set">反向字符集合</a> 一节有详细介绍和示例。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-dollar" id="special-dollar" name="special-dollar"><code>$</code></a></td>
+ <td>
+ <p>匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。</p>
+
+ <p>例如,<code>/t$/</code> 并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-asterisk" id="special-asterisk" name="special-asterisk"><code>*</code></a></td>
+ <td>
+ <p>匹配前一个表达式 0 次或多次。等价于 <code>{0,}</code>。</p>
+
+ <p>例如,<code>/bo*/</code> 会匹配 "A ghost boooooed" 中的 'booooo' 和 "A bird warbled" 中的 'b',但是在 "A goat grunted" 中不会匹配任何内容。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-plus" id="special-plus" name="special-plus"><code>+</code></a></td>
+ <td>
+ <p>匹配前面一个表达式 1 次或者多次。等价于 <code>{1,}</code>。</p>
+
+ <p>例如,<code>/a+/</code> 会匹配 "candy" 中的 'a' 和 "caaaaaaandy" 中所有的 'a',但是在 "cndy" 中不会匹配任何内容。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-questionmark" id="special-questionmark" name="special-questionmark"><code>?</code></a></td>
+ <td>
+ <p>匹配前面一个表达式 0 次或者 1 次。等价于 <code>{0,1}</code>。</p>
+
+ <p>例如,<code>/e?le?/</code> 匹配 "angel" 中的 'el'、"angle" 中的 'le' 以及 "oslo' 中的 'l'。</p>
+
+ <p>如果<strong>紧跟在任何量词 *、 +、? 或 {} 的后面</strong>,将会使量词变为<strong>非贪婪</strong>(匹配尽量少的字符),和缺省使用的<strong>贪婪模式</strong>(匹配尽可能多的字符)正好相反。例如,对 "123abc" 使用 <code>/\d+/</code> 将会匹配 "123",而使用 <code>/\d+?/</code> 则只会匹配到 "1"。</p>
+
+ <p>还用于先行断言中,如本表的 <code>x(?=y)</code> 和 <code>x(?!y)</code> 条目所述。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-dot" id="special-dot" name="special-dot"><code>.</code></a></td>
+ <td>
+ <p>(小数点)默认匹配除换行符之外的任何单个字符。</p>
+
+ <p>例如,<code>/.n/</code> 将会匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',但是不会匹配 'nay'。</p>
+
+ <p>如果 <code>s</code> ("dotAll") 标志位被设为 true,它也会匹配换行符。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-capturing-parentheses" id="special-capturing-parentheses" name="special-capturing-parentheses"><code>(x)</code></a></td>
+ <td>
+ <p>像下面的例子展示的那样,它会匹配 'x' 并且记住匹配项。其中括号被称为<em>捕获括号</em>。</p>
+
+ <p>模式 <code>/(foo) (bar) \1 \2/</code> 中的 '<code>(foo)</code>' 和 '<code>(bar)</code>' 匹配并记住字符串 "foo bar foo bar" 中前两个单词。模式中的 <code>\1</code> 和 <code>\2</code> 表示第一个和第二个被捕获括号匹配的子字符串,即 <code>foo</code> 和 <code>bar</code>,匹配了原字符串中的后两个单词。注意 <code>\1</code>、<code>\2</code>、...、<code>\n</code> 是用在正则表达式的匹配环节,详情可以参阅后文的 <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions$edit#special-backreference">\n</a> 条目。而在正则表达式的替换环节,则要使用像 <code>$1</code>、<code>$2</code>、...、<code>$n</code> 这样的语法,例如,<code>'bar foo'.replace(/(...) (...)/, '$2 $1')</code>。<code>$&amp;</code> 表示整个用于匹配的原字符串。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-non-capturing-parentheses" id="special-non-capturing-parentheses" name="special-non-capturing-parentheses"><code>(?:x)</code></a></td>
+ <td>
+ <p>匹配 'x' 但是不记住匹配项。这种括号叫作<em>非捕获括号</em>,使得你能够定义与正则表达式运算符一起使用的子表达式。看看这个例子 <code>/(?:foo){1,2}/</code>。如果表达式是 <code>/foo{1,2}/</code>,<code>{1,2}</code> 将只应用于 'foo' 的最后一个字符 'o'。如果使用非捕获括号,则 <code>{1,2}</code> 会应用于整个 'foo' 单词。更多信息,可以参阅下文的 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Using_parentheses">Using parentheses</a> 条目.</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-lookahead" id="special-lookahead" name="special-lookahead"><code>x(?=y)</code></a></td>
+ <td>
+ <p>匹配'x'仅仅当'x'后面跟着'y'.这种叫做先行断言。</p>
+
+ <p>例如,/Jack(?=Sprat)/会匹配到'Jack'仅当它后面跟着'Sprat'。/Jack(?=Sprat|Frost)/匹配‘Jack’仅当它后面跟着'Sprat'或者是‘Frost’。但是‘Sprat’和‘Frost’都不是匹配结果的一部分。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-lookahead" id="special-lookahead" name="special-lookahead"><code>(?&lt;=y)</code></a>x</td>
+ <td>
+ <p>匹配'x'仅当'x'前面是'y'.这种叫做后行断言。</p>
+
+ <p>例如,/(?&lt;=Jack)Sprat/会匹配到' Sprat '仅仅当它前面是' Jack '。/(?&lt;=Jack|Tom)Sprat/匹配‘ Sprat ’仅仅当它前面是'Jack'或者是‘Tom’。但是‘Jack’和‘Tom’都不是匹配结果的一部分。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-negated-look-ahead" id="special-negated-look-ahead" name="special-negated-look-ahead"><code>x(?!y)</code></a></td>
+ <td>
+ <p>仅仅当'x'后面不跟着'y'时匹配'x',这被称为正向否定查找。</p>
+
+ <p>例如,仅仅当这个数字后面没有跟小数点的时候,/\d+(?!\.)/ 匹配一个数字。正则表达式/\d+(?!\.)/.exec("3.141")匹配‘141’而不是‘3.141’</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>(?&lt;!<em>y</em>)<em>x</em></code></td>
+ <td>
+ <p>仅仅当'x'前面不是'y'时匹配'x',这被称为反向否定查找。</p>
+
+ <p>例如, 仅仅当这个数字前面没有负号的时候,<code>/(?&lt;!-)\d+/</code> 匹配一个数字。<br>
+ <code>/(?&lt;!-)\d+/.exec('3')</code> 匹配到 "3".<br>
+ <code>/(?&lt;!-)\d+/.exec('-3')</code> 因为这个数字前有负号,所以没有匹配到。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-or" id="special-or" name="special-or"><code>x|y</code></a></td>
+ <td>
+ <p>匹配‘x’或者‘y’。</p>
+
+ <p>例如,/green|red/匹配“green apple”中的‘green’和“red apple”中的‘red’</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n}</code></a></td>
+ <td>n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。<br>
+ 比如, /a{2}/ 不会匹配“candy”中的'a',但是会匹配“caandy”中所有的 a,以及“caaandy”中的前两个'a'。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n,}</code></a></td>
+ <td>
+ <p>n是一个正整数,匹配前一个字符至少出现了n次。</p>
+
+ <p>例如, /a{2,}/ 匹配 "aa", "aaaa" 和 "aaaaa" 但是不匹配 "a"。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-quantifier-range" id="special-quantifier-range" name="special-quantifier-range"><code>{n,m}</code></a></td>
+ <td>
+ <p>n 和 m 都是整数。匹配前面的字符至少n次,最多m次。如果 n 或者 m 的值是0, 这个值被忽略。</p>
+
+ <p>例如,/a{1, 3}/ 并不匹配“cndy”中的任意字符,匹配“candy”中的a,匹配“caandy”中的前两个a,也匹配“caaaaaaandy”中的前三个a。注意,当匹配”caaaaaaandy“时,匹配的值是“aaa”,即使原始的字符串中有更多的a。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-character-set" id="special-character-set" name="special-character-set"><code>[xyz]</code></a></td>
+ <td>一个字符集合。匹配方括号中的任意字符,包括<a href="/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types">转义序列</a>。你可以使用破折号(-)来指定一个字符范围。对于点(.)和星号(*)这样的特殊符号在一个字符集中没有特殊的意义。他们不必进行转义,不过转义也是起作用的。<br>
+ 例如,[abcd] 和[a-d]是一样的。他们都匹配"brisket"中的‘b’,也都匹配“city”中的‘c’。/[a-z.]+/ 和/[\w.]+/与字符串“test.i.ng”匹配。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-negated-character-set" id="special-negated-character-set" name="special-negated-character-set"><code>[^xyz]</code></a></td>
+ <td>
+ <p>一个反向字符集。也就是说, 它匹配任何没有包含在方括号中的字符。你可以使用破折号(-)来指定一个字符范围。任何普通字符在这里都是起作用的。</p>
+
+ <p>例如,[^abc] 和 [^a-c] 是一样的。他们匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-backspace" id="special-backspace" name="special-backspace"><code>[\b]</code></a></td>
+ <td>
+ <p>匹配一个退格(U+0008)。(不要和\b混淆了。)</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-word-boundary" id="special-word-boundary" name="special-word-boundary"><code>\b</code></a></td>
+ <td>
+ <p>匹配一个词的边界。一个词的边界就是一个词不被另外一个“字”字符跟随的位置或者前面跟其他“字”字符的位置,例如在字母和空格之间。注意,匹配中不包括匹配的字边界。换句话说,一个匹配的词的边界的内容的长度是0。(不要和[\b]混淆了)</p>
+
+ <p>使用"moon"举例:<br>
+ /\bm/匹配“moon”中的‘m’;<br>
+ /oo\b/并不匹配"moon"中的'oo',因为'oo'被一个“字”字符'n'紧跟着。<br>
+ /oon\b/匹配"moon"中的'oon',因为'oon'是这个字符串的结束部分。这样他没有被一个“字”字符紧跟着。<br>
+ /\w\b\w/将不能匹配任何字符串,因为在一个单词中间的字符永远也不可能同时满足没有“字”字符跟随和有“字”字符跟随两种情况。</p>
+
+ <div class="note">
+ <p><strong>注意:</strong> JavaScript的正则表达式引擎将<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.6">特定的字符集</a>定义为“字”字符。不在该集合中的任何字符都被认为是一个断词。这组字符相当有限:它只包括大写和小写的罗马字母,十进制数字和下划线字符。不幸的是,重要的字符,例如“<a id="none" name="none"></a>é”或“ü”,被视为断词。</p>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-non-word-boundary" id="special-non-word-boundary" name="special-non-word-boundary"><code>\B</code></a></td>
+ <td>
+ <p>匹配一个非单词边界。匹配如下几种情况:</p>
+
+ <ul>
+ <li>字符串第一个字符为非“字”字符</li>
+ <li>字符串最后一个字符为非“字”字符</li>
+ <li>两个单词字符之间</li>
+ <li>两个非单词字符之间</li>
+ <li>空字符串</li>
+ </ul>
+
+ <p>例如,/\B../匹配"noonday"中的'oo', 而/y\B../匹配"possibly yesterday"中的’yes‘</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-control" id="special-control" name="special-control"><code>\c<em>X</em></code></a></td>
+ <td>
+ <p>当X是处于A到Z之间的字符的时候,匹配字符串中的一个控制符。</p>
+
+ <p>例如,<code>/\cM/</code> 匹配字符串中的 control-M (U+000D)。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-digit" id="special-digit" name="special-digit"><code>\d</code></a></td>
+ <td>
+ <p>匹配一个数字<code>。</code><code>等价于[0-9]</code>。</p>
+
+ <p>例如, <code>/\d/</code> 或者 <code>/[0-9]/</code> 匹配"B2 is the suite number."中的'2'。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-non-digit" id="special-non-digit" name="special-non-digit"><code>\D</code></a></td>
+ <td>
+ <p>匹配一个非数字字符<code>。</code><code>等价于[^0-9]</code>。</p>
+
+ <p>例如, <code>/\D/</code> 或者 <code>/[^0-9]/</code> 匹配"B2 is the suite number."中的'B' 。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-form-feed" id="special-form-feed" name="special-form-feed"><code>\f</code></a></td>
+ <td>匹配一个换页符 (U+000C)。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-line-feed" id="special-line-feed" name="special-line-feed"><code>\n</code></a></td>
+ <td>匹配一个换行符 (U+000A)。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-carriage-return" id="special-carriage-return" name="special-carriage-return"><code>\r</code></a></td>
+ <td>匹配一个回车符 (U+000D)。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-white-space" id="special-white-space" name="special-white-space"><code>\s</code></a></td>
+ <td>
+ <p>匹配一个空白字符,包括空格、制表符、换页符和换行符。等价于[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]。</p>
+
+ <p>例如, <code>/\s\w*/</code> 匹配"foo bar."中的' bar'。</p>
+
+ <p>经测试,\s不匹配"<a href="https://unicode-table.com/cn/180E/">\u180e</a>",在当前版本Chrome(v80.0.3987.122)和Firefox(76.0.1)控制台输入/\s/.test("\u180e")均返回false。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-non-white-space" id="special-non-white-space" name="special-non-white-space"><code>\S</code></a></td>
+ <td>
+ <p>匹配一个非空白字符。等价于 <code>[^ </code>\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff<code>]</code>。</p>
+
+ <p>例如,<code>/\S\w*/</code> 匹配"foo bar."中的'foo'。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-tab" id="special-tab" name="special-tab"><code>\t</code></a></td>
+ <td>匹配一个水平制表符 (U+0009)。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-vertical-tab" id="special-vertical-tab" name="special-vertical-tab"><code>\v</code></a></td>
+ <td>匹配一个垂直制表符 (U+000B)。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-word" id="special-word" name="special-word"><code>\w</code></a></td>
+ <td>
+ <p>匹配一个单字字符(字母、数字或者下划线)。等价于 <code>[A-Za-z0-9_]</code>。</p>
+
+ <p>例如, <code>/\w/</code> 匹配 "apple," 中的 'a',"$5.28,"中的 '5' 和 "3D." 中的 '3'。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-non-word" id="special-non-word" name="special-non-word"><code>\W</code></a></td>
+ <td>
+ <p>匹配一个非单字字符。等价于 <code>[^A-Za-z0-9_]</code>。</p>
+
+ <p>例如, <code>/\W/</code> 或者 <code>/[^A-Za-z0-9_]/</code> 匹配 "50%." 中的 '%'。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-backreference" id="special-backreference" name="special-backreference"><code>\<em>n</em></code></a></td>
+ <td>
+ <p>在正则表达式中,它返回最后的第n个子捕获匹配的子字符串(捕获的数目以左括号计数)。</p>
+
+ <p>比如 <code>/apple(,)\sorange\1/</code> 匹配"apple, orange, cherry, peach."中的'apple, orange,' 。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><a href="#special-null" id="special-null" name="special-null"><code>\0</code></a></td>
+ <td>匹配 NULL(U+0000)字符, 不要在这后面跟其它小数,因为 <code>\0&lt;digits&gt;</code> 是一个八进制转义序列。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-hex-escape" id="special-hex-escape" name="special-hex-escape"><code>\xhh</code></a></td>
+ <td>匹配一个两位十六进制数(\x00-\xFF)表示的字符。</td>
+ </tr>
+ <tr>
+ <td><a href="#special-unicode-escape" id="special-unicode-escape" name="special-unicode-escape"><code>\uhhhh</code></a></td>
+ <td>匹配一个四位十六进制数表示的 UTF-16 代码单元。</td>
+ </tr>
+ <tr>
+ <td>
+ <p><code><a href="#special-unicode-escape-es6" id="special-unicode-escape-es6" name="special-unicode-escape-es6">\u{hhhh}</a>或\u{hhhhh}</code></p>
+ </td>
+ <td>(仅当设置了u标志时)匹配一个十六进制数表示的 Unicode 字符。</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Escaping">Escaping</h3>
+
+<p>如果你需要使用任何特殊字符的字面值(例如,搜索字符'*'),你必须通过在它前面放一个反斜杠来转义它。 例如,要搜索'a'后跟'*'后跟'b',你应该使用<code>/a\*b/</code>- 反斜杠“转义”字符'*',使其成为文字而非特殊符号。</p>
+
+<p>类似地,如果您正在编写正则表达式文字并且需要匹配斜杠('/'),那么需要转义它(否则,斜杠是正则终止符)。 例如,要搜索字符串“/ example /”后跟一个或多个字母字符,您需要使用<code>/\/example\/[a-z]+/i</code>——每个斜杠之前使用反斜杠使它们成为普通字符。</p>
+
+<p>要匹配文本符号反斜杠,您需要转义反斜杠。 例如,要匹配字符串“C:\”,其中“C”可以是任何字母,您将使用<code>/[A-Z]:\\/</code> —— 第一个反斜杠转义后面的那个反斜杠,因此表达式搜索单个普通字符反斜杠。</p>
+
+<p>如果将RegExp构造函数与字符串文字一起使用,请记住反斜杠是字符串文字中的转义,因此要在正则表达式中使用它,您需要在字符串文字级别转义它。 <code>/a\*b/</code> 和<code>new RegExp("a\\*b")</code>创建的表达式是相同的,搜索“a”后跟文字“*”后跟“b”。</p>
+
+<p>将用户输入转义为正则表达式中的一个字面字符串, 可以通过简单的替换来实现:</p>
+
+<pre class="brush: js notranslate">function escapeRegExp(string) {
+ return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&amp;");
+ //$&amp;表示整个被匹配的字符串
+}</pre>
+
+<p>正则表达式后的"g"是一个表示全局搜索选项或标记,将在整个字符串查找并返回所有匹配结果。这将在下面的<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions#%E9%80%9A%E8%BF%87%E6%A0%87%E5%BF%97%E8%BF%9B%E8%A1%8C%E9%AB%98%E7%BA%A7%E6%90%9C%E7%B4%A2">通过标志进行高级搜索</a>详述。</p>
+
+<p>为什么这个没有内建在JavaScript中?之前有计划在RegExp对象中添加一个Function,但在<a href="https://github.com/benjamingr/RegExp.escape/issues/37">TC39</a>中被否决了。</p>
+
+<h3 id="使用插入语">使用插入语</h3>
+
+<p>任何正则表达式的插入语都会使这部分匹配的副字符串被记忆。一旦被记忆,这个副字符串就可以被调用于其它用途,如同 <a href="#使用括号的子字符串匹配">使用括号的子字符串匹配</a>之中所述。</p>
+
+<p>比如, <code>/Chapter (\d+)\.\d*/</code> 解释了额外转义的和特殊的字符,并说明了这部分pattern应该被记忆。它精确地匹配后面跟着一个以上数字字符的字符 'Chapter ' (<code>\d</code> 意为任何数字字符,<code>+ 意为1次以上</code>),跟着一个小数点(在这个字符中本身也是一个特殊字符;小数点前的 \ 意味着这个pattern必须寻找字面字符 '.'),跟着任何数字字符0次以上。 (<code>\d</code> 意为数字字符, <code>*</code> 意为0次以上)。另外,插入语也用来记忆第一个匹配的数字字符。</p>
+
+<p>此模式可以匹配字符串"Open Chapter 4.3, paragraph 6",并且'4'将会被记住。此模式并不能匹配"Chapter 3 and 4",因为在这个字符串中'3'的后面没有点号'.'。</p>
+
+<p>括号中的"?:",这种模式匹配的子字符串将不会被记住。比如,(?:\d+)匹配一次或多次数字字符,但是不能记住匹配的字符。</p>
+
+<h2 id="使用正则表达式">使用正则表达式</h2>
+
+<p>正则表达式可以被用于 <code><a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp">RegExp</a></code> 的 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/exec"><code>exec</code></a> 和 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/test"><code>test</code></a> 方法以及 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/String"><code>String</code></a> 的 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/String/match"><code>match</code></a>、<a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/String/replace"><code>replace</code></a>、<a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/String/search"><code>search</code></a> 和 <a href="/zh-CN/docs/JavaScript/Reference/Global_Objects/String/split"><code>split</code></a> 方法。这些方法在 <a href="/zh-CN/docs/JavaScript/Reference">JavaScript 手册</a>中有详细的解释。</p>
+
+<table class="standard-table">
+ <caption>使用正则表达式的方法</caption>
+ <thead>
+ <tr>
+ <th scope="col">方法</th>
+ <th scope="col">描述</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>{{jsxref("RegExp.exec", "exec")}}</td>
+ <td>一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("RegExp.test", "test")}}</td>
+ <td>一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("String.match", "match")}}</td>
+ <td>一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("String.matchAll", "matchAll")}}</td>
+ <td>一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("String.search", "search")}}</td>
+ <td>一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("String.replace", "replace")}}</td>
+ <td>一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。</td>
+ </tr>
+ <tr>
+ <td>{{jsxref("String.split", "split")}}</td>
+ <td>一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 <code>String</code> 方法。</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>当你想要知道在一个字符串中的一个匹配是否被找到,你可以使用 test 或 search 方法;想得到更多的信息(但是比较慢)则可以使用 exec 或 match 方法。如果你使用exec 或 match 方法并且匹配成功了,那么这些方法将返回一个数组并且更新相关的正则表达式对象的属性和预定义的正则表达式对象(详见下)。如果匹配失败,那么 exec 方法返回 null(也就是false)。</p>
+
+<p>在接下来的例子中,脚本将使用exec方法在一个字符串中查找一个匹配。</p>
+
+<pre class="brush: js notranslate">var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+</pre>
+
+<p>如果你不需要访问正则表达式的属性,这个脚本通过另一个方法来创建myArray:</p>
+
+<pre class="brush: js notranslate">var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+// 和 "cdbbdbsbz".match(/d(b+)d/g); 相似。
+// 但是 "cdbbdbsbz".match(/d(b+)d/g) 输出数组 [ "dbbd" ],
+// 而 /d(b+)d/g.exec('cdbbdbsbz') 输出数组 [ "dbbd", "bb", index: 1, input: "cdbbdbsbz" ].
+
+</pre>
+
+<p>如果你想通过一个字符串构建正则表达式,那么这个脚本还有另一种方法:</p>
+
+<pre class="brush: js notranslate">var myRe = new RegExp("d(b+)d", "g");
+var myArray = myRe.exec("cdbbdbsbz");
+</pre>
+
+<p>通过这些脚本,匹配成功后将返回一个数组并且更新正则表达式的属性,如下表所示。</p>
+
+<table class="standard-table">
+ <caption>正则表达式执行后的返回信息</caption>
+ <thead>
+ <tr>
+ <th scope="col">对象</th>
+ <th scope="col">属性或索引</th>
+ <th scope="col">描述</th>
+ <th scope="col">在例子中对应的值</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td rowspan="4"><code>myArray</code></td>
+ <td></td>
+ <td>匹配到的字符串和所有被记住的子字符串。</td>
+ <td><code>["dbbd", "bb"]</code></td>
+ </tr>
+ <tr>
+ <td><code>index</code></td>
+ <td>在输入的字符串中匹配到的以0开始的索引值。</td>
+ <td><code>1</code></td>
+ </tr>
+ <tr>
+ <td><code>input</code></td>
+ <td>初始字符串。</td>
+ <td><code>"cdbbdbsbz"</code></td>
+ </tr>
+ <tr>
+ <td><code>[0]</code></td>
+ <td>最近一个匹配到的字符串。</td>
+ <td><code>"dbbd"</code></td>
+ </tr>
+ <tr>
+ <td rowspan="2"><code>myRe</code></td>
+ <td><code>lastIndex</code></td>
+ <td>开始下一个匹配的起始索引值。(这个属性只有在使用g参数时可用在 <a href="/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions#.E9.80.9A.E8.BF.87.E5.8F.82.E6.95.B0.E8.BF.9B.E8.A1.8C.E9.AB.98.E7.BA.A7.E6.90.9C.E7.B4.A2">通过参数进行高级搜索</a> 一节有详细的描述.)</td>
+ <td><code>5</code></td>
+ </tr>
+ <tr>
+ <td><code>source</code></td>
+ <td>模式字面文本。在正则表达式创建时更新,不执行。</td>
+ <td><code>"d(b+)d"</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<p>如这个例子中的第二种形式所示,你可以使用对象初始器创建一个正则表达式实例,但不分配给变量。如果你这样做,那么,每一次使用时都会创建一个新的正则表达式实例。因此,如果你不把正则表达式实例分配给一个变量,你以后将不能访问这个正则表达式实例的属性。例如,假如你有如下脚本:</p>
+
+<pre class="brush: js notranslate">var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + myRe.lastIndex);
+</pre>
+
+<p>这个脚本输出如下:</p>
+
+<pre class="notranslate">The value of lastIndex is 5
+</pre>
+
+<p>然而,如果你有如下脚本:</p>
+
+<pre class="brush: js notranslate">var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
+</pre>
+
+<p>它显示为:</p>
+
+<pre class="notranslate">The value of lastIndex is 0
+</pre>
+
+<p>当发生/d(b+)d/g使用两个不同状态的正则表达式对象,lastIndex属性会得到不同的值。如果你需要访问一个正则表达式的属性,则需要创建一个对象初始化生成器,你应该首先把它赋值给一个变量。</p>
+
+<h3 id="使用括号的子字符串匹配_2"><a id="使用括号的子字符串匹配" name="使用括号的子字符串匹配">使用括号的子字符串匹配</a></h3>
+
+<p>一个正则表达式模式使用括号,将导致相应的子匹配被记住。例如,/a(b)c /可以匹配字符串“abc”,并且记得“b”。回调这些括号中匹配的子串,使用数组元素[1],……[n]。</p>
+
+<p>使用括号匹配的子字符串的数量是无限的。返回的数组中保存所有被发现的子匹配。下面的例子说明了如何使用括号的子字符串匹配。</p>
+
+<p>下面的脚本使用replace()方法来转换字符串中的单词。在匹配到的替换文本中,脚本使用替代的$ 1,$ 2表示第一个和第二个括号的子字符串匹配。</p>
+
+<pre class="brush: js notranslate">var re = /(\w+)\s(\w+)/;
+var str = "John Smith";
+var newstr = str.replace(re, "$2, $1");
+console.log(newstr);
+</pre>
+
+<p>这个表达式输出 "Smith, John"。</p>
+
+<h3 id="通过标志进行高级搜索">通过标志进行高级搜索</h3>
+
+<p>正则表达式有六个可选参数 (<code>flags</code>) 允许全局和不分大小写搜索等。这些参数既可以单独使用也能以任意顺序一起使用, 并且被包含在正则表达式实例中。</p>
+
+<table class="standard-table">
+ <caption>正则表达式标志</caption>
+ <thead>
+ <tr>
+ <th scope="col" style="white-space: nowrap;">标志</th>
+ <th scope="col" style="white-space: nowrap;">描述</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td style="text-align: center;"><code>g</code></td>
+ <td>全局搜索。</td>
+ </tr>
+ <tr>
+ <td style="text-align: center;"><code>i</code></td>
+ <td>不区分大小写搜索。</td>
+ </tr>
+ <tr>
+ <td style="text-align: center;"><code>m</code></td>
+ <td>多行搜索。</td>
+ </tr>
+ <tr>
+ <td style="text-align: center;"><code>s</code></td>
+ <td>允许 <code>.</code> 匹配换行符。</td>
+ </tr>
+ <tr>
+ <td style="text-align: center;"><code>u</code></td>
+ <td>使用unicode码的模式进行匹配。</td>
+ </tr>
+ <tr>
+ <td style="text-align: center;"><code>y</code></td>
+ <td>执行“粘性(<code>sticky</code>)”搜索,匹配从目标字符串的当前位置开始。</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>为了在正则表达式中包含标志,请使用以下语法:</p>
+
+<pre class="brush: js notranslate">var re = /pattern/flags;
+</pre>
+
+<p>或者</p>
+
+<pre class="brush: js notranslate">var re = new RegExp("pattern", "flags");
+</pre>
+
+<p>值得注意的是,标志是一个正则表达式的一部分,它们在接下来的时间将不能添加或删除。</p>
+
+<p>例如,re = /\w+\s/g 将创建一个查找一个或多个字符后有一个空格的正则表达式,或者组合起来像此要求的字符串。</p>
+
+<pre class="brush: js notranslate">var re = /\w+\s/g;
+var str = "fee fi fo fum";
+var myArray = str.match(re);
+console.log(myArray);
+
+// ["fee ", "fi ", "fo "]
+</pre>
+
+<p>这段代码将输出 ["fee ", "fi ", "fo "]。在这个例子中,你可以将:</p>
+
+<pre class="brush: js notranslate">var re = /\w+\s/g;
+</pre>
+
+<p>替换成:</p>
+
+<pre class="brush: js notranslate">var re = new RegExp("\\w+\\s", "g");
+</pre>
+
+<p>并且能获取到相同的结果。</p>
+
+<p>使用<code>.exec()</code>方法时,与'<code>g</code>'标志关联的行为是不同的。 (“class”和“argument”的作用相反:在<code>.match()</code>的情况下,字符串类(或数据类型)拥有该方法,而正则表达式只是一个参数,而在<code>.exec()</code>的情况下,它是拥有该方法的正则表达式,其中字符串是参数。对比<em><code>str.match(re)</code></em>与<em><code>re.exec(str)</code></em> ), '<code>g</code>'标志与<code>.exec()</code>方法一起使用获得迭代进展。</p>
+
+<pre class="brush: js notranslate">var xArray; while(xArray = re.exec(str)) console.log(xArray);
+// produces:
+// ["fee ", index: 0, input: "fee fi fo fum"]
+// ["fi ", index: 4, input: "fee fi fo fum"]
+// ["fo ", index: 7, input: "fee fi fo fum"]</pre>
+
+<p>m标志用于指定多行输入字符串应该被视为多个行。如果使用m标志,^和$匹配的开始或结束输入字符串中的每一行,而不是整个字符串的开始或结束。</p>
+
+<h2 id="例子">例子</h2>
+
+<p>以下例子说明了一些正则表达式的用途。</p>
+
+<h3 id="改变输入字符串的顺序">改变输入字符串的顺序</h3>
+
+<p>以下例子解释了正则表达式的构成和 <code>string.split()</code> 以及 <code>string.replace()</code>的用途。它会整理一个只有粗略格式的含有全名(名字首先出现)的输入字符串,这个字符串被空格、换行符和一个分号分隔。最终,它会颠倒名字顺序(姓氏首先出现)和list的类型。</p>
+
+<pre class="brush: js notranslate">// 下面这个姓名字符串包含了多个空格和制表符,
+// 且在姓和名之间可能有多个空格和制表符。
+var names = "Orange Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
+
+var output = ["---------- Original String\n", names + "\n"];
+
+// 准备两个模式的正则表达式放进数组里。
+// 分割该字符串放进数组里。
+
+// 匹配模式:匹配一个分号及紧接其前后所有可能出现的连续的不可见符号。
+var pattern = /\s*;\s*/;
+
+// 把通过上述匹配模式分割的字符串放进一个叫做nameList的数组里面。
+var nameList = names.split(pattern);
+
+// 新建一个匹配模式:匹配一个或多个连续的不可见字符及其前后紧接着由
+// 一个或多个连续的基本拉丁字母表中的字母、数字和下划线组成的字符串
+// 用一对圆括号来捕获该模式中的一部分匹配结果。
+// 捕获的结果稍后会用到。
+pattern = /(\w+)\s+(\w+)/;
+
+// 新建一个数组 bySurnameList 用来临时存放正在处理的名字。
+var bySurnameList = [];
+
+// 输出 nameList 的元素并且把 nameList 里的名字
+// 用逗号接空格的模式把姓和名分割开来然后存放进数组 bySurnameList 中。
+//
+// 下面的这个替换方法把 nameList 里的元素用 $2, $1 的模式
+// (第二个捕获的匹配结果紧接着一个逗号一个空格然后紧接着第一个捕获的匹配结果)替换了
+// 变量 $1 和变量 $2 是上面所捕获的匹配结果。
+
+output.push("---------- After Split by Regular Expression");
+
+var i, len;
+for (i = 0, len = nameList.length; i &lt; len; i++) {
+ output.push(nameList[i]);
+ bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
+}
+
+// 输出新的数组
+output.push("---------- Names Reversed");
+for (i = 0, len = bySurnameList.length; i &lt; len; i++){
+ output.push(bySurnameList[i]);
+}
+
+// 根据姓来排序,然后输出排序后的数组。
+bySurnameList.sort();
+output.push("---------- Sorted");
+for (i = 0, len = bySurnameList.length; i &lt; len; i++){
+ output.push(bySurnameList[i]);
+}
+
+output.push("---------- End");
+
+console.log(output.join("\n"));
+</pre>
+
+<h3 id="用特殊字符检验输入">用特殊字符检验输入</h3>
+
+<p>在以下例子中,我们期望用户输入一个电话号码。当用户点击“Check”按钮,我们的脚本开始检查这些数字是否合法。如果数字合法(匹配正则表达式所规定的字符序列),脚本显示一条感谢用户的信息并确认该数字。如果这串数字不合法,脚本提示用户电话号码不合法。.</p>
+
+<p>包含非捕获括号 <code>(?:</code> 这个正则表达式寻找三个数字字符<code>\d{3}</code> 或者 <code>|</code> 一个左半括号<code>\(</code>跟着三位数字<code>\d{3}</code>, 跟着一个封闭括号 <code>\)</code>, (结束非捕获括号 <code>)</code>), 后跟着一个短破折号或正斜杠或小数点,随后跟随三个数字字符,当记忆字符 <code>([-\/\.])捕获并记住,后面跟着三位小数</code> <code>\d{3},再后面跟随记住的破折号、正斜杠或小数点</code> <code>\1,最后跟着四位小数</code> <code>\d{4}。</code></p>
+
+<p>当用户按下 Enter 设置 RegExp.input,这些变化也能被激活。</p>
+
+<pre class="brush: html notranslate">&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+ &lt;head&gt;
+ &lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;
+ &lt;meta http-equiv="Content-Script-Type" content="text/javascript"&gt;
+ &lt;script type="text/javascript"&gt;
+ var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
+ function testInfo(phoneInput) {
+ var OK = re.exec(phoneInput.value);
+ if (!OK)
+ window.alert(phoneInput.value + ' isn\'t a phone number with area code!');
+ else
+ window.alert('Thanks, your phone number is ' + OK[0]);
+ }
+ &lt;/script&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ &lt;p&gt;Enter your phone number (with area code) and then click "Check".
+ &lt;br&gt;The expected format is like ###-###-####.&lt;/p&gt;
+ &lt;form action="#"&gt;
+ &lt;input id="phone"&gt;&lt;button onclick="testInfo(document.getElementById('phone'));"&gt;Check&lt;/button&gt;
+ &lt;/form&gt;
+ &lt;/body&gt;
+&lt;/html&gt;
+</pre>
+
+<div>{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html
new file mode 100644
index 0000000000..0b0252022a
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/unicode_property_escapes/index.html
@@ -0,0 +1,171 @@
+---
+title: Unicode property escapes
+slug: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes
+---
+<p>{{jsSidebar("JavaScript Guide")}}</p>
+
+<p><strong>Unicode property escapes</strong> <a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions">正则表达式</a> 支持根据 Unicode 属性进行匹配,例如我们可以用它来匹配出表情、标点符号、字母(甚至适用特定语言或文字)等。同一符号可以拥有多种 Unicode 属性,属性则有 binary ("boolean-like") 和 non-binary 之分。</p>
+
+<div>{{EmbedInteractiveExample("pages/js/regexp-unicode-property-escapes.html", "taller")}}</div>
+
+<div class="blockIndicator note">
+<p><strong>Note: </strong>使用 Unicode 属性转义依靠 <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode"><code>\u</code> 标识</a>,<code>\u</code> 表示该字符串被视为一串 Unicode 代码点。参考 <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode">RegExp.prototype.nicode</a></code>.</p>
+</div>
+
+<div class="blockIndicator note">
+<p><strong>Note:</strong> 某些 Unicode 属性比<a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类</a>(如 <code>\w</code> 只匹配拉丁字母 <code>a</code> 到 <code>z</code>)包含更多的字符  ,但后者浏览器兼容性更好 (截至2020 一月).</p>
+</div>
+
+<h2 id="句法">句法</h2>
+
+<div class="hidden">The following section is also duplicated on <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">this cheatsheet</a>. Do not forget to edit it as well, thanks!</div>
+
+<pre class="brush: js notranslate">// Non-binary 属性
+\p{<em>Unicode属性值</em>}
+\p{<em>Unicode属性名</em>=<em>Unicode属性值</em>}
+
+// Binary and non-binary 属性
+\p{<em>UnicodeBinary属性名</em>}
+
+// \P 为 \p 取反
+\P{<em>Unicode属性值</em>}
+\P{<em>UnicodeBinary属性名</em>}
+</pre>
+
+<ul>
+ <li><a href="https://unicode.org/reports/tr18/#General_Category_Property">General_Category</a> (<code>gc</code>)</li>
+ <li><a href="https://unicode.org/reports/tr24/#Script">Script</a> (<code>sc</code>)</li>
+ <li><a href="https://unicode.org/reports/tr24/#Script_Extensions">Script_Extensions</a> (<code>scx</code>)</li>
+</ul>
+
+<p>参考 <a href="https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt">PropertyValueAliases.txt<span style="display: none;"> </span></a></p>
+
+<dl>
+ <dt>UnicodeBinary属性名</dt>
+ <dd><a href="https://tc39.es/ecma262/#table-binary-unicode-properties">Binary 属性</a>名. E.g.: <code><a href="https://unicode.org/reports/tr18/#General_Category_Property">ASCII</a></code>. <code><a href="https://unicode.org/reports/tr44/#Alphabetic">Alpha</a></code>, <code>Math</code>, <code><a href="https://unicode.org/reports/tr44/#Diacritic">Diacritic</a></code>, <code><a href="https://unicode.org/reports/tr51/#Emoji_Properties">Emoji</a></code>, <code><a href="https://unicode.org/reports/tr44/#Hex_Digit">Hex_Digit</a></code>, <code>Math</code>, <code><a href="https://unicode.org/reports/tr44/#White_Space">White_space</a></code>, 等. 另见 <a href="https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt">Unicode Data PropList.txt</a>.</dd>
+ <dt>Unicode属性名</dt>
+ <dd><a href="https://tc39.es/ecma262/#table-nonbinary-unicode-properties">Non-binary</a> 属性名:</dd>
+ <dt>Unicode属性值</dt>
+ <dd>很多值有同名或简写(e.g. 对应着 <code>General_Category</code> 属性名的属性值 <code>Decimal_Number</code> 可以写作 <code>Nd</code>, <code>digit</code>, 或 <code>Decimal_Number</code>). 大多数属性值的 <em><code>Unicode属性名</code></em> 和等号可以省去。如果想明确某 <em><code>Unicode属性名</code></em>,必须给出它的值。</dd>
+</dl>
+
+<div class="blockIndicator note">
+<p><strong>Note:</strong> 因为可使用的属性和值太多,这里不一一赘述,仅提供几个例子。</p>
+</div>
+
+<h2 id="基本原理">基本原理</h2>
+
+<p>在 ES2018 之前,JavaScript 没有强有效的方式用匹配出不同<code>文字</code>(如马其顿语,希腊语,Georgian 等)或不同 <code>属性名</code> (如 Emoji 等)的字符。另见 <a href="https://github.com/tc39/proposal-regexp-unicode-property-escapes">tc39 Proposal on Unicode Property Escapes</a>.</p>
+
+<h2 id="例子">例子</h2>
+
+<h3 id="(一般类别)General_categories">(一般类别)General categories</h3>
+
+<p>General categories 对 Unicode 字符进行分类,子类别用于精确定义类别。长名和简写的 Unicode 属性转义都可用.</p>
+
+<p>它们可匹配字母、数字、符号、标点符号、空格等等。一般类别详见 <a href="https://unicode.org/reports/tr18/#General_Category_Property">the Unicode specification</a>.</p>
+
+<pre class="brush: js notranslate">// finding all the letters of a text
+let story = "It’s the Cheshire Cat: now I shall have somebody to talk to.";
+
+// Most explicit form
+story.match(/\p{General_Category=Letter}/gu);
+
+// It is not mandatory to use the property name for General categories
+story.match(/\p{Letter}/gu);
+
+// This is equivalent (short alias):
+story.match(/\p{L}/gu);
+
+// This is also equivalent (conjunction of all the subcategories using short aliases)
+story.match(/\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/gu);
+</pre>
+
+<h3 id="文字(Script)和文字扩充(Script_Extensions)">文字(Script)和文字扩充(Script_Extensions)</h3>
+
+<p>某些语言使用不同的文字,如英语和西班牙语使用拉丁文,而阿拉伯语和俄语用阿拉伯文和俄文。<code>Script</code> 和 <code>Script_Extensions</code> Unicode 属性允许正则表达式根据字符所属的<code>文字</code>或该文字所属的<code>文字扩充</code>进行匹配。</p>
+
+<p>比如,<code>A</code> 属于 <code>拉丁文</code>,<code>ε</code> 属于<code>希腊(Greek)</code>文。</p>
+
+<pre class="brush: js notranslate">let mixedCharacters = "aεЛ";
+
+// Using the canonical "long" name of the script
+mixedCharacters.match(/\p{Script=Latin}/u); // a
+
+// Using a short alias for the script
+mixedCharacters.match(/\p{Script=Grek}/u); // ε
+
+// Using the short name Sc for the Script property
+mixedCharacters.match(/\p{Sc=Cyrillic}/u); // Л
+</pre>
+
+<p>详见 <a href="https://unicode.org/reports/tr24/#Script">the Unicode specification</a> 和 <a href="https://tc39.es/ecma262/#table-unicode-script-values">Scripts table in the ECMAScript specification</a>.</p>
+
+<p>某字符用于多种文字时,<code>Script</code> 优先匹配最主要使用那个字符的文字。如果想要根据非主要的文字进行匹配,我们可以使用 <code>Script_Extensions</code> 属性 (简写为<code>Scx</code>).</p>
+
+<pre class="brush: js notranslate">// ٢ is the digit 2 in Arabic-Indic notation
+// while it is predominantly written within the Arabic script
+// it can also be written in the Thaana script
+
+"٢".match(/\p{Script=Thaana}/u);
+// null as Thaana is not the predominant script        super()
+
+"٢".match(/\p{Script_Extensions=Thaana}/u);
+// ["٢", index: 0, input: "٢", groups: undefined]
+</pre>
+
+<h3 id="Unicode_属性转义_vs._字符类">Unicode 属性转义 vs. 字符类</h3>
+
+<p>JavaScript 正则表达式可以使用 <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">字符类</a> 尤其是 <code>\w</code> 或 <code>\d</code> 匹配字母或数字,然而,这样的形式只匹配拉丁文字的字符 (换言之,<code>a</code> 到 <code>z</code>、 <code>A</code> 到 <code>Z</code> 的 <code>\w</code> 和 <code>0</code> 到 <code>9</code> 的 <code>\d</code>),见<a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes#Looking_for_a_word_from_Unicode_characters">例子</a>,这样的使用放到非拉丁文本中是有些蠢的。</p>
+
+<p>Unicode 属性转义 categories 包含更多字符, <code>\p{Letter}</code> 或 <code>\p{Number}</code> 将会适用于任何文字。</p>
+
+<pre class="brush: js notranslate">// Trying to use ranges to avoid \w limitations:
+
+const nonEnglishText = "Приключения Алисы в Стране чудес";
+const regexpBMPWord = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
+// BMP goes through U+0000 to U+FFFF but space is U+0020
+
+console.table(nonEnglishText.match(regexpBMPWord));
+
+// Using Unicode property escapes instead
+const regexpUPE = /\p{L}+/gu;
+console.table(nonEnglishText.match(regexpUPE));
+</pre>
+
+<h2 id="Specifications">Specifications</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Specification</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-runtime-semantics-unicodematchproperty-p', 'RegExp: Unicode property escapes')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browser_compatibility">Browser compatibility</h2>
+
+<p>For browser compatibility information, check out the <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">main Regular Expressions compatibility table</a>.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Regular expressions guide</a>
+
+ <ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">Character classes</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">Assertions</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers">Quantifiers</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">Groups and ranges</a></li>
+ </ul>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">The <code>RegExp()</code> constructor</a></li>
+ <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/unicode">RegExp.prototype.unicode</a></code></li>
+ <li><a href="https://en.wikipedia.org/wiki/Unicode_character_property">Unicode character property — Wikipedia</a></li>
+ <li><a href="https://2ality.com/2017/07/regexp-unicode-property-escapes.html">A blog post from Axel Rauschmayer about Unicode property escapes</a></li>
+ <li><a href="https://unicode.org/reports/tr18/#Categories">The Unicode document for Unicode properties</a></li>
+</ul>
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/量词/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/量词/index.html
new file mode 100644
index 0000000000..bcc2a35e13
--- /dev/null
+++ b/files/zh-cn/web/javascript/guide/regular_expressions/量词/index.html
@@ -0,0 +1,170 @@
+---
+title: 量词
+slug: Web/JavaScript/Guide/Regular_Expressions/量词
+translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers
+---
+<p>{{jsSidebar("JavaScript Guide")}}</p>
+
+<p>量词表示要匹配的字符或表达式的数量。</p>
+
+<div>{{EmbedInteractiveExample("pages/js/regexp-quantifiers.html", "taller")}}</div>
+
+<h2 id="类型">类型</h2>
+
+<div class="hidden">The following table is also duplicated on <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">this cheatsheet</a>. Do not forget to edit it as well, thanks!</div>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th scope="col">Characters</th>
+ <th scope="col">Meaning</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><code><em>x</em>*</code></td>
+ <td>
+ <p>将前面的项“x”匹配0次或更多次。例如,/bo*/匹配“A ghost booooed”中的“boooo”和“A bird warbled”中的“b”,但在“A goat grunt”中没有匹配。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code><em>x</em>+</code></td>
+ <td>
+ <p>将前一项“x”匹配1次或更多次。等价于{1,}。例如,/a+/匹配“candy”中的“a”和“caaaaaaandy”中的“a”。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code><em>x</em>?</code></td>
+ <td>
+ <p>将前面的项“x”匹配0或1次。例如,/ e ?勒?/匹配angel中的el和angle中的le。</p>
+
+ <p>如果立即在任何量词*、+、?或{}之后使用,则使量词是非贪婪的(匹配最小次数),而不是默认的贪婪的(匹配最大次数)。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code><em>x</em>{<em>n</em>}</code></td>
+ <td>
+ <p>其中“n”是一个正整数,与前一项“x”的n次匹配。例如,<code>/a{2}/ </code>不匹配“candy”中的“a”,但它匹配“caandy”中的所有“a”,以及“caaandy”中的前两个“a”。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code><em>x</em>{<em>n</em>,}</code></td>
+ <td>
+ <p>其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。例如,<code>/a{2,}/</code>不匹配“candy”中的“a”,但匹配“caandy”和“caaaaaaandy”中的所有a。</p>
+ </td>
+ </tr>
+ <tr>
+ <td><code><em>x</em>{<em>n</em>,<em>m</em>}</code></td>
+ <td>
+ <p>其中,“n”是0或一个正整数,“m”是一个正整数,而m &gt; n至少与前一项“x”匹配,最多与“m”匹配。例如,/a{1,3}/不匹配“cndy”中的“a”,“candy”中的“a”,“caandy”中的两个“a”,以及“caaaaaaandy”中的前三个“a”。注意,当匹配“caaaaaaandy”时,匹配的是“aaa”,即使原始字符串中有更多的“a”。</p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p><code><em>x</em>*?</code><br>
+ <code><em>x</em>+?</code><br>
+ <code><em>x</em>??</code><br>
+ <code><em>x</em>{n}?</code><br>
+ <code><em>x</em>{n,}?</code><br>
+ <code><em>x</em>{n,m}?</code></p>
+ </td>
+ <td>
+ <p>默认情况下,像 <code>* </code>和 <code>+ </code>这样的量词是“贪婪的”,这意味着它们试图匹配尽可能多的字符串。?量词后面的字符使量词“非贪婪”:意思是它一旦找到匹配就会停止。例如,给定一个字符串“some &lt;foo&gt; &lt;bar&gt; new &lt;/bar&gt; &lt;/foo&gt; thing”:</p>
+
+ <ul>
+ <li><code>/&lt;.*&gt;/</code> will match "&lt;foo&gt; &lt;bar&gt; new &lt;/bar&gt; &lt;/foo&gt;"</li>
+ <li><code>/&lt;.*?&gt;/</code> will match "&lt;foo&gt;"</li>
+ </ul>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="举例说明">举例说明</h2>
+
+<h3 id="重复模式">重复模式</h3>
+
+<pre class="brush: js notranslate">var wordEndingWithAs = /\w+a+/;
+var delicateMessage = "This is Spartaaaaaaa";
+
+console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]</pre>
+
+<h3 id="计算字符集">计算字符集</h3>
+
+<pre class="brush: js notranslate">var singleLetterWord = /\b\w\b/g;
+var notSoLongWord = /\b\w{1,6}\b/g;
+var loooongWord = /\b\w{13,}\b/g;
+
+var sentence = "Why do I have to learn multiplication table?";
+
+console.table(sentence.match(singleLetterWord)); // ["I"]
+console.table(sentence.match(notSoLongWord)); // <span class="message-body-wrapper"><span class="message-flex-body"><span class="devtools-monospace message-body"><span class="objectBox objectBox-array"><span class="arrayLeftBracket">[ </span><span class="objectBox objectBox-string">"Why"</span>, <span class="objectBox objectBox-string">"do"</span>, <span class="objectBox objectBox-string">"I"</span>, <span class="objectBox objectBox-string">"have"</span>, <span class="objectBox objectBox-string">"to"</span>, <span class="objectBox objectBox-string">"learn"</span>, <span class="objectBox objectBox-string">"table"</span><span class="arrayRightBracket"> ]</span></span></span></span></span>
+console.table(sentence.match(loooongWord)); // ["multiplication"]可选可选字符
+</pre>
+
+<h3 id="可选字符"> 可选字符</h3>
+
+<pre class="brush: js notranslate">var britishText = "He asked his neighbour a favour.";
+var americanText = "He asked his neighbor a favor.";
+
+var regexpEnding = /\w+ou?r/g;
+// \w+ One or several letters
+// o followed by an "o",
+// u? optionally followed by a "u"
+// r followed by an "r"
+
+console.table(britishText.match(regexpEnding));
+// ["neighbour", "favour"]
+
+console.table(americanText.match(regexpEnding));
+// ["neighbor", "favor"]
+</pre>
+
+<h3 id="贪婪_与_非贪婪的">贪婪 与 非贪婪的</h3>
+
+<pre class="brush: js notranslate">var text = "I must be getting somewhere near the centre of the earth.";
+var greedyRegexp = /[\w ]+/;
+// [\w ] a letter of the latin alphabet or a whitespace
+// + one or several times
+
+console.log(text.match(greedyRegexp)[0]);
+// "I must be getting somewhere near the centre of the earth"
+// almost all of the text matches (leaves out the dot character)
+
+var nonGreedyRegexp = /[\w ]+?/; // Notice the question mark
+console.log(text.match(nonGreedyRegexp));
+// "I"
+// The match is the smallest one possible
+</pre>
+
+<h2 id="规范"><strong>规范</strong></h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Specification</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-quantifier', 'RegExp: Quantifiers')}}</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="浏览器支持">浏览器支持</h2>
+
+<p>For browser compatibility information, check out the <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Browser_compatibility">main Regular Expressions compatibility table</a>.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Regular expressions guide</a>
+
+ <ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">Character classes</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">Assertions</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes">Unicode property escapes</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">Groups and ranges</a></li>
+ </ul>
+ </li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp">The <code>RegExp()</code> constructor</a></li>
+</ul>