aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/global_objects/regexp/exec/index.html
blob: 6648813f0073bd5db5f5286960ec04bf779e038d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
---
title: RegExp.prototype.exec()
slug: Web/JavaScript/Reference/Global_Objects/RegExp/exec
tags:
  - '## lastIndex bug???'
  - JavaScript
  - Method
  - Prototype
  - RegExp
  - Regular Expressions
translation_of: Web/JavaScript/Reference/Global_Objects/RegExp/exec
---
<div>{{JSRef}}</div>

<p><code><strong>exec() </strong></code>方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 {{jsxref("null")}}</p>

<p>在设置了 {{jsxref("RegExp.global", "global")}}{{jsxref("RegExp.sticky", "sticky")}} 标志位的情况下(如 <code>/foo/g</code> or <code>/foo/y</code>),JavaScript {{jsxref("RegExp")}} 对象是<strong>有状态</strong>的。他们会将上次成功匹配后的位置记录在 <span style="font-size: 1rem; letter-spacing: -0.00278rem;">{{jsxref("RegExp.lastIndex", "lastIndex")}} 属性中。使用此特性,</span><code style="font-size: 1rem; letter-spacing: -0.00278rem;">exec()</code><span style="font-size: 1rem; letter-spacing: -0.00278rem;"> 可用来对单个字符串中的多次匹配结果进行逐条的遍历(包括捕获到的匹配),而相比之下, {{jsxref("String.prototype.match()")}} 只会返回匹配到的结果。</span></p>

<p>如果你只是为了判断是否匹配(true或 false),可以使用 {{jsxref("RegExp.test()")}} 方法,或者 {{jsxref("String.search()")}} 方法。</p>

<div>{{EmbedInteractiveExample("pages/js/regexp-prototype-exec.html")}}</div>



<h2 id="Syntax" name="Syntax">语法</h2>

<pre class="syntaxbox"><var>regexObj</var>.exec(<var>str</var>)</pre>

<h3 id="Parameters" name="Parameters">参数</h3>

<dl>
 <dt><code>str</code></dt>
 <dd>要匹配正则表达式的字符串。</dd>
</dl>

<h3 id="Description" name="Description">返回值</h3>

<p>如果匹配成功,<code>exec()</code> 方法返回一个数组(包含额外的属性 <code>index</code> 和 <code>input</code> ,参见下方表格),并更新正则表达式对象的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性。完全匹配成功的文本将作为返回数组的第一项,从第二项起,后续每项都对应正则表达式内捕获括号里匹配成功的文本。</p>

<p>如果匹配失败,<code>exec()</code> 方法返回 {{jsxref("null")}},并将 {{jsxref("RegExp.lastIndex", "lastIndex")}} 重置为 0 。</p>

<h2 id="描述">描述</h2>

<p>考虑以下示例:</p>

<pre class="brush: js">// Match "quick brown" followed by "jumps", ignoring characters in between
// Remember "brown" and "jumps"
// Ignore case
var re = /quick\s(brown).+?(jumps)/ig;
var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');
</pre>

<p>下表列出这个脚本的返回值:</p>

<table class="fullwidth-table">
 <tbody>
  <tr>
   <td class="header">对象</td>
   <td class="header">属性/索引</td>
   <td class="header">描述</td>
   <td class="header">例子</td>
  </tr>
  <tr>
   <td rowspan="4"><code>result</code></td>
   <td><code>[0]</code></td>
   <td>匹配的全部字符串</td>
   <td><code>Quick Brown Fox Jumps</code></td>
  </tr>
  <tr>
   <td><code>[1], ...[<em>n</em> ]</code></td>
   <td>括号中的分组捕获</td>
   <td><code>[1] = Brown<br>
    [2] = Jumps</code></td>
  </tr>
  <tr>
   <td><code>index</code></td>
   <td>匹配到的字符位于原始字符串的基于0的索引值</td>
   <td><code>4</code></td>
  </tr>
  <tr>
   <td><code>input</code></td>
   <td>原始字符串</td>
   <td><code>The Quick Brown Fox Jumps Over The Lazy Dog</code></td>
  </tr>
  <tr>
   <td rowspan="5"><code>re</code></td>
   <td><code>lastIndex</code></td>
   <td>下一次匹配开始的位置</td>
   <td><code>25</code></td>
  </tr>
  <tr>
   <td><code>ignoreCase</code></td>
   <td>是否使用了 "<code>i</code>" 标记使正则匹配忽略大小写</td>
   <td><code>true</code></td>
  </tr>
  <tr>
   <td><code>global</code></td>
   <td>是否使用了 "<code>g</code>" 标记来进行全局的匹配.</td>
   <td><code>true</code></td>
  </tr>
  <tr>
   <td><code>multiline</code></td>
   <td>
    <p>是否使用了 "<code>m</code>" 标记使正则工作在多行模式(也就是,^ 和 $ 可以匹配字符串中每一行的开始和结束(行是由 \n 或 \r 分割的),而不只是整个输入字符串的最开始和最末尾处。)</p>
   </td>
   <td><code>false</code></td>
  </tr>
  <tr>
   <td><code>source</code></td>
   <td>正则匹配的字符串</td>
   <td><code>quick\s(brown).+?(jumps)</code></td>
  </tr>
 </tbody>
</table>

<h2 id="示例">示例</h2>

<h3 id="查找所有匹配">查找所有匹配</h3>

<p>当正则表达式使用 "<code>g</code>" 标志时,可以多次执行 <code>exec</code> 方法来查找同一个字符串中的成功匹配。当你这样做时,查找将从正则表达式的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 属性指定的位置开始。({{jsxref("RegExp.test", "test()")}} 也会更新 <code>lastIndex</code> 属性)。注意,即使再次查找的字符串不是原查找字符串时,{{jsxref("RegExp.lastIndex", "lastIndex")}} 也不会被重置,它依旧会从记录的 {{jsxref("RegExp.lastIndex", "lastIndex")}} 开始。</p>

<p>例如,你使用下面的脚本:</p>

<pre class="brush: js">var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found ' + myArray[0] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}
</pre>

<p>脚本运行结果如下:</p>

<pre>Found abb. Next match starts at 3
Found ab. Next match starts at 9
</pre>

<div class="blockIndicator warning">
<p>注意:不要把正则表达式字面量(或者{{jsxref("RegExp")}}构造器)放在 <code>while</code> 条件表达式里。由于每次迭代时 {{jsxref("RegExp.lastIndex", "lastIndex")}} 的属性都被重置,如果匹配,将会造成一个死循环。并且要确保使用了'g'标记来进行全局的匹配,否则同样会造成死循环。</p>
</div>

<h3 id="结合_RegExp_字面量使用_exec">结合 <code>RegExp</code> 字面量使用 <code>exec()</code></h3>

<p>你也可以直接使用 <code>exec()</code> 而不是创建一个 {{jsxref("RegExp")}}  对象:</p>

<pre class="brush: js">var matches = /(hello \S+)/.exec('This is a hello world!');
console.log(matches[1]);
</pre>

<p>运行上面的代码,控制台会输出"hello world!" 字符串。</p>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES3')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.2.</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-15.10.6.21', 'RegExp.exec')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-regexp.prototype.exec', 'RegExp.exec')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-regexp.prototype.exec', 'RegExp.exec')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>

<div>


<p>{{Compat("javascript.builtins.RegExp.exec")}}</p>
</div>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Regular Expressions</a> chapter in the <a href="/en-US/docs/Web/JavaScript/Guide">JavaScript Guide</a></li>
 <li>{{jsxref("RegExp")}}</li>
</ul>