【JavaScript】 split()で正規表現を使って文字列分割してみる
更新日:2021/01/10
JavaScriptのsplit()は、文字列を分割して配列にセットするメソッドです。
分割する文字列は正規表現で指定できるのを知っていますか?
split()で正規表現を使用すると、より細やかな文字列分割ができます。
split()の使い方
まずはsplit()の使い方を確認してみます。
次のようなカンマ区切りの文字列があるとする。
const text = "123,456,789";
カンマでサクッと分割したいな
というとき、
const data = text.split( "," );
とすると、引数で渡した文字列","で分割することができます。
結果は次のようになります。
console.log( data ); // 結果: [ "123" , " 456" , "789" ]
このように、配列に分割してくれる使い勝手がいいメソッドなのです。
split()で正規表現を使ってみる
複数の文字列で分割したいとき、正規表現を使うと簡単です。
次のテキストを、カンマだけでなく、"|"でも分割したいとします。
const text = "123,45|67,89";
次のようにsplitメソッドの引数に正規表現を指定します。
const data = text.split( //____TAGFOLDER____// );
console.log( data ); // 結果: [ "123", "45", "67", "89" ]
JavaScriptの正規表現については、こちらを参照してください。
【JavaScript】 正規表現まとめメモ
分割文字を文字列の前に残す
例えば次のような文字列があるとします。
const text = "1:朝起きる2:朝食を食べる3:学校へ行く";
これを次のように分割する方法を考えてみます。
[0] : "1:朝起きる"
[1] : "2:朝食を食べる"
[2] : "3:学校へ行く"
1桁(固定桁)の場合
分割文字を文字列の前に残すには、split()の引数に肯定的先読みを使用した正規表現を指定します。
肯定的先読み
文字の後ろに指定したパターンがあるとき一致する。
abcde(?=パターン)
このマッチング終了後は、文字(上の例ではabced)の後、つまり(?=パターン)に一致した文字から始まります。
ここでは、/(?=\d:)/を使用することで、"2:"や"3:"の前で文字列を分割することができます。
const text = "1:朝起きる2:朝食を食べる3:学校へ行く";
const data = text.split( /(?=\d:)/ );
console.log( data ); // 結果: [ "1:朝起きる", "2:朝食を食べる", "3:学校へ行く" ]
"02","03","99"など桁が増えても桁数が固定なら、次のように桁数に合わせて\dを指定すればOKです。
/(?=\d\d:)/
桁が変動する場合
次に、数字の桁が変動するケースを考えてみます。
まずは間違いパターンから。
正規表現で+は、1回以上の繰り返しをあらわします。
そこで次のような書き方が思いつきます。
/(?=\d+:)/
const text = "1:朝起きる2:朝食を食べる3:学校へ行く100:寝る";
const data = text.split( /(?=\d+:)/ );
console.log( data );
// 結果: [ "1:朝起きる", "2:朝食を食べる", "3:学校へ行く", "1", "0", "0:寝る" ]
最後の"100:"が、一桁ごとに分割されてしまいました。
"3:学校へ行く"の処理後に残りの"100:寝る"を処理する際、次のように判断されているからです。
- "1"の後に続くのが"00:寝る"である
- "00:"はパターンにマッチする
- "1"は分割対象である
そこで否定的後読みを使用して、"00:"の前に数字がないことを確認するパターンを作成します。
否定的後読み
文字の前に指定したパターンがないとき一致する。
(?<!パターン)abcde
/(?<!\d)(?=\d+:)/を使用します。
const text = "1:朝起きる2:朝食を食べる3:学校へ行く100:寝る";
const data = text.split( /(?<!\d)(?=\d+:)/ );
console.log( data );
// 結果: [ "1:朝起きる", "2:朝食を食べる", "3:学校へ行く", "100:寝る" ]
分割文字を文字列の後ろに残す
次のような文字列を読点で区切り、区切りとして使用した読点も文字列に含める方法を考えてみます。
区切り文字が固定の場合
分割文字を文字列の後ろに残すには、split()の引数に肯定的後読みを使用した正規表現を指定します。
肯定的後読み
文字の前に指定したパターンがあるとき一致する。
(?<=パターン)abcde
読点で区切りには、/(?<=。)/を使用します。
const text = "こんにちは。いい天気です。昨日はありがとう。";
const data = text.split( /(?<=。)/ );
console.log( data ); // 結果: [ "こんにちは。", "いい天気です。", "昨日はありがとう。" ]
句読点で区切るときは、/(?<=[。、])/を使用します。
const text = "こんにちは、いい天気です。昨日はありがとう。";
const data = text.split( /(?<=[。、])/ );
console.log( data ); // 結果: [ "こんにちは、", "いい天気です。", "昨日はありがとう。" ]
区切りが連続する場合
読点が連続した場合も一つの文字列として扱うケースを考えてみます。
分割文字を文字列の前に残すの桁が変動する場合と同じ理由で、次のような繰り返しパターンは使用できません。
/(?<=。+)/
そこで否定的先読みを使用します。
否定的先読み
文字の後に指定したパターンがないとき一致する。
abcde(?!パターン)
/(?<=。+)(?!。)/を使用します。
const text = "こんにちは。いい天気です。。。昨日はありがとう。";
const data = text.split( /(?<=。+)(?!。)/ );
console.log( data );
// 結果:[ "こんにちは。", "いい天気です。。。", "昨日はありがとう。" ]
区切り文字を個別に残す
これまで紹介してきたように区切り文字を文字列に付加するのではなくて、配列内に個別に格納する方法を考えてみます。
正規表現のパターンを( )で囲むことで配列に格納できます。
const text = "こんにちは。いい天気です。昨日はありがとう。";
const data = text.split( /(。)/ );
console.log( data );
// 結果: [ "こんにちは", "。", "いい天気です", "。", "昨日はありがとう", "。", "" ]
句点が続いたら一つにまとめたい場合は、これまでとは異なり繰り返しパターンを使用できます。
const text = "こんにちは。いい天気です。。。昨日はありがとう。";
const data = text.split( /(。+)/ );
console.log( data );
// 結果: [ "こんにちは", "。", "いい天気です", "。。。", "昨日はありがとう", "。", "" ]
まとめ
split()で正規表現を使用すると、より細やかな文字列分割ができます。
しかし複雑なことをしようとするとうまくいかないことが多いので、そんなときはreplaceを使用しましょう。
更新日:2021/01/10
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。