【JavaScript】 テキストファイルを正規表現で検索するときの注意点
更新日:2020/06/12
htmlなどのテキストファイルをそのままの形で読み込んできて、正規表現で検索したらハマったのでメモ。
複数行にわたるマッチングでハマる
たとえばhtmlのdivタグの中身を正規表現でマッチングさせたいとき、次のようにした。
const divInner = /<div.*?>(.*?)<\/div/.exec( htmldata );
このコードは次のようなhtmlデータだと問題ない。
<div><p>テストデータ</p></div>
しかし、次のように複数行にまたがるとnullを返す。
<div>
<p>テストデータ</p>
</div>
. は改行にマッチングしなかった
理由はとても単純でした。
おまじないのように書いていた .?* ですが、最初の . は改行にマッチングしません。
つまり改行が現れると、そこで止まるわけです。
比較的最近(2018年)ですが、JavaScriptの正規表現にオプションフラグ "s" が追加されていました。
これを使用すれば . が改行にマッチングします。
const divInner = /<div.*?>(.*?)<\/div/s.exec( htmldata );
しかし比較的新しいだけあって、古いブラウザでは動作しません。
"s"を使用しないで改行にもマッチングさせる
正規表現のパターンはよく見ると、数値にマッチするパターン(\d)と数値以外にマッチするパターン(\D)があります。
この両方を[ ]で使用すると、全てにマッチしてくれます。
const divInner = /<div.*?>([\d\D]*?)<\/div/.exec( htmldata );
同じように、数値・アルファベット・アンダースコア(_)に関する\wと\W。
改行・スペース・タブ・空白に関する\sと\Sも使用できます。
const divInner = /<div.*?>([\w\W]*?)<\/div/.exec( htmldata );
const divInner = /<div.*?>([\s\S]*?)<\/div/.exec( htmldata );
ブラウザが "s" に対応しているか確認する
オプションフラグ "s" の導入に伴い、RegExpにdotAllプロパティが追加されています。
"s"が使用できないブラウザは、このプロパティが存在しないため、次の方法でチェックできます。
const a = new RegExp("","s");
console.log( a.dotAll === undefined ? "使用できません" : "使用できます");
"s"が使用できる場合、 . が改行にマッチングするならdotAllプロパティの値がtrueに。
マッチングしないなら、falseになります。
// オプション "s" を指定しない
console.log( new RegExp( "" ).dotAll ); // false
// オプション "s" を指定する
console.log( new RegExp( "" , "s" ).dotAll ); // true
更新日:2020/06/12
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。