JavaScriptでは正規表現を使ってテキストをマッチすることができます。ただし、対象となる文字列に改行が含まれる場合書き方にひと工夫が必要になります。
ここでは、改行を含んだテキストに対して正規表現でマッチさせる方法についてまとめています。
結論
結論から言うと次の記述を使います。
[\s\S]*?
次にこれが何を示しているのか解説します。
[\s\S]*? の意味とは?(もしくは[\s\S\n]*?)
[\s\S]*?
は分解すると以下の4つの要素に分解できます。(ドルマークはバックスラッシュに置き換えてください)
記号 | 意味 |
---|---|
[~] | ~のいずれか1文字にマッチ |
\s | 空白文字 (= 半角スペース、\t、\n、\r、\f) |
\S | 空白文字以外(\s以外のすべて) |
*? | 直前のパターンの0回以上繰り返し(最短一致) |
\sか\Sのどちらか、つまり、すべて要素の繰り返しで、かつ、最短一致にするという意味です。何気に最短一致の *?
の表記が重要です。
[\s\S\n]*?でもいいのか?
\nを入れて、[\s\S\n]*?と記載しているパターンも見かけます。これは改行文字も含めるですが、\Sに含まれているのであってもなくてもどちらも一緒になります。
記号 | 意味 |
---|---|
\n | 改行文字 (= CR+LF, LF, CR) |
実例
記述方法
例えば、次のような文字列があるとします。
str = `
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ
*メールアドレス* test@gmail.com
*電話番号* 12345678
*ゲーム参加人数* 10
*参加者のお名前* ①小平哲郎
②田中正二郎
③米山米夫
*人数(6歳未満)* 2
*付き添い* 2
*アレルギー* ある
*アレルギーの詳細* パクチー
*ご希望や特筆事項(自由入力)* Lorem ipsum dolor sit amet,
consectetur adipiscing
elit,
*お支払い方法* 銀行振込
*ゲーム参加人数 × 10* ¥180,000
*合計* ¥180,000`;
ここで参加者の名前は①~③まで改行されています。3人の「参加者のお名前」のみを取得したい場合は以下のように記述します。
let result = str.match(/参加者のお名前[\s\S]*?\*人数/)[0].replace("参加者のお名前* ", "").replace("*人数", "");
console.logで出力すると以下のようになります。
①小平哲郎
②田中正二郎
③米山米夫
完璧です。
コードの解説
str = `
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ
*メールアドレス* test@gmail.com
*電話番号* 12345678
*ゲーム参加人数* 10
*参加者のお名前* ①小平哲郎
②田中正二郎
③米山米夫
*人数(6歳未満)* 2
*付き添い* 2
*アレルギー* ある
*アレルギーの詳細* パクチー
*ご希望や特筆事項(自由入力)* Lorem ipsum dolor sit amet,
consectetur adipiscing
elit,
*お支払い方法* 銀行振込
*ゲーム参加人数 × 10* ¥180,000
*合計* ¥180,000`;
let result = str.match(/参加者のお名前[\s\S]*?\*人数/)[0].replace("参加者のお名前* ", "").replace("*人数", "");
上記の例ではmatchの中は/参加者のお名前[\s\S]*?*人数/
となっています。
これで、「参加者のお名前」に一致したところから、改行も含めてずーっとマッチさせ、「*人数」と一致するところまでを最短一致で探します。
文字列としての「*(アスタリスク)」の検索方法
正規表現における「*(アスタリスク)」は0回以上繰り返し(最長一致)なので、文字列として検索したい場合はバックスラッシュでエスケープします。記述は「\*」となります。
matchの注意点
matchメソッドの結果は正規表現で一致したものだけが返ってくるわけではありません。一致する結果、文字数、検索対象の文字列、グループなどの情報を返します。
[①マッチした文字列, ②index(文字数), ③input(検索対象), ④groups]
▼実例
let result = str.match(/参加者のお名前[\s\S]*?\*人数/);
console.log(result);
//結果
[
'参加者のお名前* ①小平哲郎\n②田中正二郎\n③米山米夫\n*人数',
index: 87,
input: '\n' +
'*苗字* 山田\n' +
'*名前* 卓也\n' +
'*ヨミガナ* ヤマダ タクヤ\n' +
'*メールアドレス* test@gmail.com\n' +
'*電話番号* 12345678\n' +
'*ゲーム参加人数* 10\n' +
'*参加者のお名前* ①小平哲郎\n' +
'②田中正二郎\n' +
'③米山米夫\n' +
'*人数(6歳未満)* 2\n' +
'*付き添い* 2\n' +
'*アレルギー* ある\n' +
'*アレルギーの詳細* パクチー\n' +
'*ご希望や特筆事項(自由入力)* Lorem ipsum dolor sit amet,\n' +
'consectetur adipiscing\n' +
'elit,\n' +
'*お支払い方法* 銀行振込\n' +
'*ゲーム参加人数 × 10* ¥180,000\n' +
'*合計* ¥180,000',
groups: undefined
]
基本的に欲しい情報はマッチした部分のみなので、配列番号の0を指定します。これで、マッチした文字列のみを取得することができます。
let result = str.match(/参加者のお名前[\s\S]*?\*人数/)[0];
console.log(result);
//結果
参加者のお名前* ①小平哲郎
②田中正二郎
③米山米夫
*人数
replace
名前以外はいらないので、repalceメソッドを使って不要な部分を削除します。
replace("検索対象", "置き換える文字列")
▼実例
str.match(/参加者のお名前[\s\S]*?\*人数/)[0].replace("参加者のお名前* ", "").replace("*人数", "")
これによりほしい部分だけを取得することができます。
str = `
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ
*メールアドレス* test@gmail.com
*電話番号* 12345678
*ゲーム参加人数* 10
*参加者のお名前* ①小平哲郎
②田中正二郎
③米山米夫
*人数(6歳未満)* 2
*付き添い* 2
*アレルギー* ある
*アレルギーの詳細* パクチー
*ご希望や特筆事項(自由入力)* Lorem ipsum dolor sit amet,
consectetur adipiscing
elit,
*お支払い方法* 銀行振込
*ゲーム参加人数 × 10* ¥180,000
*合計* ¥180,000`;
let result = str.match(/参加者のお名前[\s\S]*?\*人数/)[0].replace("参加者のお名前* ", "").replace("*人数", "");
console.log(result);
//出力結果
①小平哲郎
②田中正二郎
③米山米夫
1行だけの場合 (.*)
なお、改行部分は含めず1行のみで正規表現をかけたい場合は (.*)
を使います。
(.*)
記号 | 意味 |
---|---|
(~) | パターンのグループ |
. | 任意の1文字 |
* | 直前のパターンの0回以上繰り返し(最長一致) |
つまり、任意の1文字の繰り返しを繰り返すということです。改行は含まないため、改行が出てきたところで検索が強制終了となります。
▼実例
str = `
*苗字* 山田
*名前* 卓也
*ヨミガナ* ヤマダ タクヤ`;
let result = str.match(/苗字(.*)/)[0];
console.log(result);
//結果
苗字* 山田