フラグ m で、複数行モードを有効にできます。
これは ^ と $ の動作にのみ影響します。
複数行モードでは、文字列の始めと終わりだけでなく、行の始まりと終わりにもマッチします。
行の開始 ^ の検索
下の例では、テキストは複数行です。パターン /^\d+/gm はそれぞれの行の先頭から数字を取ります。:
let str = `1st place: Winnie
2nd place: Piglet
33rd place: Eeyore`;
alert( str.match(/^\d+/gm) ); // 1, 2, 33
m フラグがない場合は、最初の数値だけがマッチします:
let str = `1st place: Winnie
2nd place: Piglet
33rd place: Eeyore`;
alert( str.match(/^\d+/g) ); // 1
これは、デフォルトではキャレット ^ はテキストの先頭にのみマッチし、複数行モードでは – 行の始まりがマッチするためです。
“行の開始” は正式には “改行の直後” を意味します: 複数行モードでの ^ は改行文字 \n が前にあるすべての位置にマッチします。
行の終わり $ の検索
ドル記号 $ も同様に振る舞います。
正規表現 \d$ は各行で最後の数字を見つけます。:
let str = `Winnie: 1
Piglet: 2
Eeyore: 3`;
alert( str.match(/\d$/gm) ); // 1,2,3
フラグ m がなければ、ドル $ は文字列全体の終わりにのみマッチします。なので、最後の数字だけが見つかるでしょう。
“行の終わり” は正式には “改行の直前” を意味します: 複数行モードでの $ は改行文字 \n が続くすべての位置にマッチします。
^ $ の代わりに \n を検索する
改行を見つけるには、アンカー ^ と $ だけでなく、改行文字 \n を使うこともできます。
違いは何でしょう?例を見てみましょう。
ここでは \d$ の代わりに \d\n を使って検索します:
let str = `Winnie: 1
Piglet: 2
Eeyore: 3`;
alert( str.match(/\d\n/gm) ); // 1\n,2\n
ご覧の通り、3つではなく2つマッチします。
これは 3 の後に改行がないためです(ですがテキストの終わりはあるので、$ にはマッチします)。
もう1つの違い: すべてのマッチ結果には、改行文字 \n を含みます。アンカー ^ $ (条件(行の開始/終了)のみのテスト)とは異なり、\n は文字なので、結果に含まれます。
したがって、パターンの \n は、結果に改行を含めたいときに利用され、アンカーは行の先頭/末尾を探したいときに使われます。
コメント
<code>タグを使ってください。複数行の場合は<pre>を、10行を超える場合にはサンドボックスを使ってください(plnkr, JSBin, codepen…)。