👮‍♂️

【JS】正規表現で必要な情報を抜き出してみる!

2023/03/04に公開

以下リンク先の記事で作成したNext.jsのアプリで、正規表現を用いて、必要な情報を抜き出しました。この時の内容を記事にしていきます。
アニメリスト検索アプリ

抜き出したい情報のパターンを調べる

まずどういった情報が欲しいのか説明します。しょぼいカレンダーというサービスのAPIを叩いて、以下のようなテキストデータを取得することができました(長いです)。こちらは1アニメに対する情報となります。この中からアニメのキャストの情報だけを抜き出したいと私は考えました。

*リンク\r\n-[[公式 https://onimai.jp/]]\r\n-[[Twitter https://twitter.com/onimai_anime]]\r\n-[[YouTube(TOHO animation) https://www.youtube.com/@TOHOanimation]]\r\n\r\n*メモ\r\n**Twitter・YouTube\r\n-毎週月曜ABEMA配信版に沿ったオーディオコメンタリーを配信\r\n\r\n*スタッフ\r\n:原作:ねことうふ\r\n:掲載誌:月刊ComicRex(一迅社)\r\n:監督:藤井慎吾\r\n:シリーズ構成:横手美智子\r\n:キャラクターデザイン:今村亮\r\n:美術監督:小林雅代\r\n:色彩設計:土居真紀子\r\n:メインアニメーター:みとん、松隈勇樹、内山玄基、Kay Yu\r\n:撮影監督:伏原あかね\r\n:編集:岡祐司\r\n:音響監督:吉田光平\r\n:音響効果:長谷川卓也\r\n:音響制作:ビットグルーヴプロモーション\r\n:音楽:阿知波大輔、桶狭間ありさ\r\n:音楽制作:東宝ミュージック\r\n:プロデュース:EGG FIRM\r\n:制作:スタジオバインド\r\n:製作:「おにまい」製作委員会(東宝、博報堂DYミュージック&ピクチャーズ、一迅社、AT-X、BS11、ぴあ、ポニーキャニオン、ムービック、TOKYO MX、ビットグルーヴプロモーション、EGG FIRM)\r\n\r\n*オープニングテーマ「アイデン貞貞メルトダウン」\r\n:作詞・作曲・編曲:やしきん\r\n:歌:えなこ feat.P丸様。\r\n\r\n*エンディングテーマ「ひめごと*クライシスターズ」\r\n:作詞・作曲・編曲:おぐらあすか\r\n:歌:ONIMAI SISTERES(高野麻里佳、石原夏織、金元寿子、津田美波)\r\n\r\n*キャスト\r\n:緒山まひろ:高野麻里佳\r\n:緒山みはり:石原夏織\r\n:穂月かえで:金元寿子\r\n:穂月もみじ:津田美波\r\n:桜花あさひ:優木かな\r\n:室崎みよ:日岡なつみ\r\n\r\n*次回予告イラスト\r\n:#1:松尾祐輔\r\n:#2:米山舞\r\n:#3:Kay Yu\r\n:#4:中村豊\r\n:#5:石田可奈

正規表現でキャスト情報を抜き出すためには、キャストがどのようなパターンで記載されるかを把握しなければいけません。そのため、他のアニメのレスポンスも確認し、キャスト情報を抜き出す条件を以下のように考えました。
①【キャストの後に情報がある場合】
*キャスト〜*で囲まれた部分
②【キャストの後に情報がない場合】
*キャスト〜で末尾まで全部

上に示すテキストデータはキャスト情報の後に次回予告イラストの項目が入ってくるのでキャストの後に情報がある場合となります。

正規表現

ではパターンがわかったところで、正規表現を用いて情報を抜き出していきます。初めに今回難しかった点を挙げると、私自身あまり正規表現に慣れていないということもあったのですが、特殊文字や改行「\r\n」があったことで、より苦労したかと思います。改行が含まれるテキストをconsole.logで確認しても改行文字としては表示されなくなったりするので、そのあたりも実際のデータと見ている表示が異なるということで正規表現を使う上では混乱しましたね。
正規表現を手軽に確認するには以下のサイトが非常に役立ちました。
正規表現チェッカー

正規表現をわかりやすくまとめている人はたくさんいらっしゃるので、参考になったものを記事の最後に記載しておきます!

必要なキャスト情報を抜き出す

①の時は以下の正規表現で上手くいきました。

/\*キャスト[\s\S]*\*/

この時取得できる情報としては以下のようになります。

*キャスト\r\n:緒山まひろ:高野麻里佳\r\n:緒山みはり:石原夏織\r\n:穂月かえで:金元寿子\r\n:穂月もみじ:津田美波\r\n:桜花あさひ:優木かな\r\n:室崎みよ:日岡なつみ\r\n\r\n*

この時使った主な正規表現パターンを以下にまとめます。

文字 説明
\ 次の文字をエスケープしてくれる
* 直前の文字の0回以上の繰り返しにマッチする
\s 空白文字に一致
\S 空白以外の文字に一致

今回で言うとまず「*」を文字として認識したかったので、その文字の前には「\」を入れてエスケープしています。「*」は[\s\S]が0回以上の繰り返しにマッチするという意味でも使われているので、ややこしいですが、こちらはエスケープしていないということを見ていただきたいです。また、初めは[\s\S]の部分に「.」を用いていたのですが、「.」は改行文字以外の文字になるので、今回のように途中で「\r\n」が入ってくる正規表現にマッチしません。[\s\S]で空白も空白以外も全部の文字にマッチするといった感じになるかと思います。

この後はこの①の場合を基に話を進めていきますが、一応②の場合の正規表現も見てみましょう。以下のような感じで、「*キャスト」から後は末尾までを取得すればいいような記述になっています。

/\*キャスト[\s\S]*/

キャスト情報を抜き出すという部分のコードは以下のようになります。①、②で場合分けをして、matchメソッドでマッチしたものを配列に格納しています。

let dataCast = []
if (dataComment.match(/\*キャスト[\s\S]*\*/)) {
  dataCast = dataComment.match(/\*キャスト[\s\S]*\*/);
} else {
  dataCast = dataComment.match(/\*キャスト[\s\S]*/);
} 

不要な部分を削除して配列に

最終的にはキャスト情報をキャラ名と声優名だけにして配列して渡したかったので、不要な部分を削除していきます。
まず頭の「*キャスト\r\n」と末尾の「\r\n*」が不要なのでreplaceメソッドを用いて消していきます。

const castText = dataCast[0].replace(/\*キャスト\r\n/,"").replace(/\r\n\*/,"")

データとしては以下のようにキャラ名と声優名の情報がほとんどになりました。

:緒山まひろ:高野麻里佳\r\n:緒山みはり:石原夏織\r\n:穂月かえで:金元寿子\r\n:穂月もみじ:津田美波\r\n:桜花あさひ:優木かな\r\n:室崎みよ:日岡なつみ\r\n

キャラごとに改行(\r\n)で区切っているので、これを利用してキャラと声優がセットになるように配列にしていく処理が以下のコードです。

const castArray = castText.split(/\r\n/);

これでキャラ名と声優がセットになった配列が完成しました。しかし、色々なアニメに関して挙動を確かめたところ、配列の要素が空文字の部分が出来上がってしまっていたので、以下のコードで空文字の場合は配列から除く処理をしました。

const castDisplayData = castArray.filter(function(s){return s !== "";});

これで不要な情報が含まれていないキャスト情報の配列が完成しました。
完成したデータは以下のようなイメージです。

[":緒山まひろ:高野麻里佳", ":緒山みはり:石原夏織", ":穂月かえで:金元寿子", ":穂月もみじ:津田美波", ":桜花あさひ:優木かな", ":室崎みよ:日岡なつみ"]

ここまでのコードの全体像

ここまで個別にコードを紹介してきましたが、全てまとめた実際のコードを以下に紹介します。

// キャスト情報の抜き出し(キャスト情報の後にテキストがある場合とない場合の2パターンがある)
let dataCast = []
if (dataComment.match(/\*キャスト[\s\S]*\*/)) {
  dataCast = dataComment.match(/\*キャスト[\s\S]*\*/);
} else {
  dataCast = dataComment.match(/\*キャスト[\s\S]*/);
} 
// 不要な部分を取り除く
const castText = dataCast[0].replace(/\*キャスト\r\n/,"").replace(/\r\n\*/,"")
// 改行を区切りとして配列に変換する
const castArray = castText.split(/\r\n/);
// 配列の空要素を削除
const castDisplayData = castArray.filter(function(s){return s !== "";});

興味があれば以下のソースコードから更にファイル全体のコードを確認することができます。
アニメリスト検索アプリのソースコード

まとめ

正規表現は初めは難しいですが、地道に試していけば、欲しいデータを取り出すことができました。やってみた感想としては、得られる情報がどんなパターンで書かれているかの把握が一番大事だと思いました。最後まで読んで下さり、ありがとうございます。

参考

JavaScript 正規表現まとめ
正規表現を理解してみる

Discussion