aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/javascript/guide/regular_expressions/assertions/index.html
blob: e92e05b3129aa213828ca149c8026990cafc6e28 (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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
---
title: 言明
slug: Web/JavaScript/Guide/Regular_Expressions/Assertions
tags:
  - Assertions
  - JavaScript
  - Reference
  - Regular Expressions
  - regex
translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions
---
<p>{{jsSidebar("JavaScript Guide")}}{{draft}}</p>

<p>言明には、 行や単語の始まり・終わりを示す、境界や、(先読み、後読み、条件式を含む)何らかの方法でマッチが可能なことを示す、その他のパターンが含まれます。</p>

<h2 id="Types" name="Types">種類</h2>

<h3 id="境界型の言明">境界型の言明</h3>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">文字</th>
   <th scope="col">意味</th>
  </tr>
  <tr>
   <td><code>^</code></td>
   <td>
    <p>入力の先頭にマッチします。複数行フラグが true にセットされている場合は、改行文字の直後にもマッチします。例えば <code>/^A/</code> は "an A" の 'A' にはマッチしませんが、"An E" の 'A' にはマッチします。</p>

    <div class="blockIndicator note">
    <p>この文字は、文字<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">集合</a>パターンの先頭にある場合は異なる意味を持ちます。</p>
    </div>
   </td>
  </tr>
  <tr>
   <td><code>$</code></td>
   <td>
    <p>入力の末尾にマッチします。複数行フラグが true にセットされている場合は、改行文字の直前にもマッチします。例えば <code>/t$/</code> は "eater" の "t" にはマッチしませんが、"eat" の "t" にはマッチします。</p>
   </td>
  </tr>
  <tr>
   <td><code>\b</code></td>
   <td>
    <p>単語の区切りにマッチします。これは、単語構成文字と後に続く非単語構成文字の間、または非単語構成文字と後に続く単語構成文字の間、または文字列の先頭・最後です。単語の区切りはマッチする「文字」ではありません。アンカーのように、単語の区切りはマッチした部分に含まれません。言い換えると、マッチした単語の区切りの長さは 0 です。</p>

    <p>入力文字に "moon" を使用した例:</p>

    <ul>
     <li><code>/\bm/</code> は "m" にマッチします。これは `\b` が文字列の先頭に存在するからです。</li>
     <li><code>/oo\b/</code> は "oo" にマッチしません。これは '\b' の前後に単語構成文字があるためです。</li>
     <li><code>/oon\b/</code> は "oon" にマッチします。これは、文字列の終端であるためです。</li>
     <li><code>/\w\b\w/</code> はどこにもマッチしないでしょう。これは、'\b' の前後に単語構成文字があるためです。</li>
    </ul>

    <p>バックスペース文字 ([\b]) については<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes">文字クラス</a>を見てください。</p>
   </td>
  </tr>
  <tr>
   <td><code>\B</code></td>
   <td>
    <p>単語の区切り以外にマッチします。マッチするのは以下の場合です:</p>

    <ul>
     <li>文字列の先頭の文字の前</li>
     <li>文字列の終端の文字の後</li>
     <li>単語内の 2 文字の間</li>
     <li>2 つの単語ではない文字の間</li>
     <li>空文字列</li>
    </ul>

    <p>例えば <code>/\B../</code> は "noonday" の 'oo' に、<code>/y\B./</code> は "possibly yesterday" の 'ye' にマッチします。</p>
   </td>
  </tr>
 </thead>
</table>

<h3 id="その他の言明">その他の言明</h3>

<div class="blockIndicator note">
<p><code>?</code> 文字は数量詞として使うことができます。</p>
</div>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">文字</th>
   <th scope="col">意味</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>x(?=y)</td>
   <td>
    <p><strong>先読み言明:</strong> <em><code>x</code></em><em><code>y</code></em> が続く場合のみ <em><code>x</code></em> にマッチします。例えば <code>/Jack(?=Sprat)/</code> は "Jack" の後に "Sprat" が続く場合のみ "Jack" にマッチします。<br>
     <code>/Jack(?=Sprat|Frost)/</code> は "Jack" の後ろに "Sprat" または "Frost" が続く場合のみ "Jack" にマッチします。しかしながら、"Sprat" も "Frost" もマッチの結果には表れません。</p>
   </td>
  </tr>
  <tr>
   <td>x(?!y)</td>
   <td>
    <p><strong>否定先読み言明:</strong> <em><code>x</code></em><code><em>y</em></code> が続かない場合のみ <em><code>x</code></em> にマッチします。例えば <code>/\d+(?!\.)/</code> は後ろに小数点が続かない数値にマッチします。正規表現 <code>/\d+(?!\.)/.exec("3.141")</code> は "141" にマッチしますが "3.141" にはマッチしません。</p>
   </td>
  </tr>
  <tr>
   <td>(?&lt;=y)x</td>
   <td>
    <p><strong>後読み言明:</strong> <code><em>y</em></code><em><code>x</code></em> が続く場合のみ <code><em>x</em></code> にマッチします。例えば、<code>/(?&lt;=Jack)Sprat/</code> は "Jack" に続く "Sprat" のみにマッチします。 <code>/(?&lt;=Jack|Tom)Sprat/</code> は "Jack" または "Tom" に続く "Sprat" のみにマッチします。しかしながら、"Jack" も "Tom" もマッチの結果には表れません。</p>
   </td>
  </tr>
  <tr>
   <td>(?&lt;!y)x</td>
   <td>
    <p><strong>否定後読み言明:</strong> <em><code>y</code></em><code><em>x</em></code> が続かない場合のみ <em><code>x</code></em> にマッチします。例えば、<code>/(?&lt;!-)\d+/</code> は、マイナス記号のつかない数字のみにマッチします。 <code>/(?&lt;!-)\d+/.exec('3')</code> は "3" がマッチします。 <code>/(?&lt;!-)\d+/.exec('-3')</code> はマイナス記号に数字が続いているため、マッチが見つかりません。</p>
   </td>
  </tr>
 </tbody>
</table>

<h2 id="Examples" name="Examples"></h2>

<h3 id="基本的な境界型の例">基本的な境界型の例</h3>

<pre class="brush: js">// おかしい文字列を修正するために正規表現の境界を利用します。
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;

// 1) 文字列の最初と改行の直後のマッチを修正するために ^ を利用します。
buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
console.log(1, buggyMultiline); // 'tey', 'tangs' を 'hey', 'hangs' に修正します。 'traa' は対象外です。

// 2) テキストの末尾を修正するために $ を利用します。
buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
console.log(2, buggyMultiline); // 'traa' を 'tree' に修正します。

// 3) 単語と空白の間の境界の右の文字にマッチさせるために \b を利用します。
buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
console.log(3, buggyMultiline); // 'ihe' を修正しますが、'light'は対象外です。

// 4) エンティティの境界内の文字にマッチするために \B を利用します。
fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
console.log(4, fixedMultiline); // 'greon' を修正しますが、'on' は対象外です。</pre>

<h3 id="制御文字を利用した入力の開始へのマッチ">^ 制御文字を利用した入力の開始へのマッチ</h3>

<p> <code>^</code> は、通常、単語の開始にマッチさせるために利用します。この例では、<code>/^A/ </code>という正規表現で 'A' で始まるフルーツを取得します。ここでの <code>^</code> は、入力の開始を示すという、たった 1 つの役割を果たしています。適切なフルーツを選択するために<a href="/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions">アロー</a> 関数で <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">filter </a>メソッドを用います。</p>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruits <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Apple"</span><span class="punctuation token">,</span> <span class="string token">"Watermelon"</span><span class="punctuation token">,</span> <span class="string token">"Orange"</span><span class="punctuation token">,</span> <span class="string token">"Avocado"</span><span class="punctuation token">,</span> <span class="string token">"Strawberry"</span><span class="punctuation token">]</span><span class="punctuation token">;</span>

<span class="comment token">// /^A/ 正規表現で 'A' で始まるフルーツを選択します。</span>
<span class="comment token">// ここでの'^' 制御記号は「入力の開始にマッチする」という 1 つの役割だけで利用されています。</span>

<span class="keyword token">let</span> fruitsStartsWithA <span class="operator token">=</span> fruits<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">fruit</span> <span class="operator token">=&gt;</span> <span class="regex token">/^A/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>fruit<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>fruitsStartsWithA<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Apple', 'Avocado' ]</span></code></pre>

<p>2 番目の例での <code>^</code> は、入力の開始へのマッチと、<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">グル―プ</a>で用いられた場合の文字集合の否定または補集合という、両方で利用されています。</p>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruits <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Apple"</span><span class="punctuation token">,</span> <span class="string token">"Watermelon"</span><span class="punctuation token">,</span> <span class="string token">"Orange"</span><span class="punctuation token">,</span> <span class="string token">"Avocado"</span><span class="punctuation token">,</span> <span class="string token">"Strawberry"</span><span class="punctuation token">]</span><span class="punctuation token">;</span>

<span class="comment token">// /^[^A]/ という正規表現で 'A' で始まらないフルーツを選択します。</span>
<span class="comment token">// この例では、'^' 制御記号は 2 つの意味を表しています。</span>
<span class="comment token">// 1) 入力の開始にマッチ
// 2) [^A]という文字集合の否定または補集合: </span>
<span class="comment token">// つまり、角括弧で囲まれたものでないあらゆるものにマッチします</span>

<span class="keyword token">let</span> fruitsStartsWithNotA <span class="operator token">=</span> fruits<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">fruit</span> <span class="operator token">=&gt;</span> <span class="regex token">/^[^A]/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>fruit<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>

console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>fruitsStartsWithNotA<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Watermelon', 'Orange', 'Strawberry' ]</span></code></pre>

<h3 id="単語の境界にマッチ">単語の境界にマッチ</h3>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> fruitsWithDescription <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">"Red apple"</span><span class="punctuation token">,</span> <span class="string token">"Orange orange"</span><span class="punctuation token">,</span> <span class="string token">"Green Avocado"</span><span class="punctuation token">]</span><span class="punctuation token">;</span>

<span class="comment token">// 単語の終わりに 'en' または 'ed' を含む記述を選択します。</span>
<span class="keyword token">let</span> enEdSelection <span class="operator token">=</span> fruitsWithDescription<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span><span class="parameter token">descr</span> <span class="operator token">=&gt;</span> <span class="regex token">/(en|ed)\b/</span><span class="punctuation token">.</span><span class="function token">test</span><span class="punctuation token">(</span>descr<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>

console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>enEdSelection<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Red apple', 'Green Avocado' ]</span></code></pre>

<h3 id="先読み言明">先読み言明</h3>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// JS Lookahead assertion x(?=y)</span>

<span class="keyword token">let</span> regex <span class="operator token">=</span> <span class="regex token">/First(?= test)/g</span><span class="punctuation token">;</span>

console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'First test'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'First' ]</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'First peach'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// null</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'This is a First test in a year.'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'First' ]</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">'This is a First peach in a month.'</span><span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>regex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// null</span></code></pre>

<h3 id="基本的な否定先読み言明">基本的な否定先読み言明</h3>

<p>例えば、<code style="font-size: 1rem; letter-spacing: -0.00278rem;">/\d+(?!\.)/</code><span style="font-size: 1rem; letter-spacing: -0.00278rem;"> は小数点が後に続かない数値にだけマッチします。</span><code>/\d+(?!\.)/.exec('3.141')</code> は "141" にマッチしますが、 "3" にはマッチしません。</p>

<pre class="brush: js line-numbers language-js"><code class="language-js">console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="regex token">/\d+(?!\.)/g</span><span class="punctuation token">.</span><span class="function token">exec</span><span class="punctuation token">(</span><span class="string token">'3.141'</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ '141', index: 2, input: '3.141' ]</span></code></pre>

<h3 id="言明と範囲における_!_の組み合わせの異なる意味での利用">言明と範囲における '?!' の組み合わせの異なる意味での利用</h3>

<p> <code>?!</code> の組み合わせを利用するとき、<a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions">言明</a> <code>/x(?!y)/ </code><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges">範囲</a> <code>[^?!]</code>では異なる意味を持ちます。</p>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> orangeNotLemon <span class="operator token">=</span> <span class="string token">"Do you want to have an orange? Yes, I do not want to have a lemon!"</span><span class="punctuation token">;</span>

<span class="comment token">// 言明 /x(?!y)/ と範囲 /[^?!]/ では '?!' の組み合わせの利用は異なる意味を持ちます。</span>
<span class="keyword token">let</span> selectNotLemonRegex <span class="operator token">=</span> <span class="regex token">/[^?!]+have(?! a lemon)[^?!]+[?!]/gi</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>orangeNotLemon<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>selectNotLemonRegex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'Do you want to have an orange?' ]</span>

<span class="keyword token">let</span> selectNotOrangeRegex <span class="operator token">=</span> <span class="regex token">/[^?!]+have(?! an orange)[^?!]+[?!]/gi</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>orangeNotLemon<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span>selectNotOrangeRegex<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ ' Yes, I do not want to have a lemon!' ]</span></code></pre>

<h3 id="後読み言明">後読み言明</h3>

<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">let</span> oranges <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'ripe orange A '</span><span class="punctuation token">,</span> <span class="string token">'green orange B'</span><span class="punctuation token">,</span> <span class="string token">'ripe orange C'</span><span class="punctuation token">,</span><span class="punctuation token">]</span><span class="punctuation token">;</span>

<span class="keyword token">let</span> ripe_oranges <span class="operator token">=</span> oranges<span class="punctuation token">.</span><span class="function token">filter</span><span class="punctuation token">(</span> <span class="parameter token">fruit</span> <span class="operator token">=&gt;</span> fruit<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span><span class="regex token">/(?&lt;=ripe )orange/</span><span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>ripe_oranges<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// [ 'ripe orange A ', 'ripe orange C' ]</span></code></pre>

<h2 id="仕様">仕様</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">仕様</th>
   <th scope="col">策定状況</th>
   <th scope="col">コメント</th>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="ブラウザサポート">ブラウザサポート</h2>

<div>


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

<h2 id="See_also" name="See_also">関連情報</h2>

<ul>
 <li><a href="/ja/docs/Web/JavaScript/Guide/Regular_Expressions">正規表現</a></li>
 <li><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp"><code>RegExp()</code> コンストラクタ</a></li>
</ul>