>100 Views
January 18, 24
スライド概要
1/8 正規表現について
正規表現の利用ケース
2/8
・バリデーション
入力された文字列が形式に則っているかチェックする
(例)郵便番号が7桁の数値となっているか、
^\w{3}-?\w{4}$ などでチェックする
・文字列の抽出
大量の文字列から必要な部分のみ抽出する
(例)Eメール原稿からメールアドレスのみを抽出するとき、
^[a-zA-Z0-9.!#$%&'*+¥/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:¥.[a-zA-Z0-9-]+)*$
などで検索
様々な文字列のパターンが想定される場合に正規表現を使う
正規表現のマッチ範囲 3/8 ・なるべく全てのパターンにマッチさせられるか ・想定外の文字列のマッチを防ぐにはどう書くか ・・・想定されるパターン ・・・検索するパターン 検索パターンが少ない 検索パターンが多い これらのパターン差を0にするように正規表現を記述することが理想的
正規表現の注意点 ・想定外のパターンに注意 ファーストネームやファミリーネームのバリデーションは[A-Z][a-z]*でよい? Robert Downey Jr.などのパターンは当てはまらない ・メタ文字のエスケープ忘れに注意 (aaa|bbb).comとした場合、aaa.comとbbb.comのみマッチする? 「.」を「¥.」としてないので、aaaxcomなどもマッチしてしまう ・「.」は改行にはマッチしない 検索したいパターンに改行が含まれていた場合、「.*」ではスルーされてしまう 4/8
より速い検索を行うために 5/8 正規表現によるパフォーマンスへの影響度合いは、 正規表現と「マッチしない」パターンの数で決まる この部分と これ以降を検索 ① ② ②の正規表現はパターンがより具体的であり、 マッチしないパターンが①に比べて少ないため、 ②の方が速く検索が完了する より具体的かつマッチパターンが少ない正規表現だと素早く検索できる
悪い正規表現を書いてしまうと 6/8 「.*」は、正規表現エンジンのすべてのイベントをスキャンするため、 文字列の読み込みとバックトラックを繰り返す 最後まで読み取った後、最初のスペースまで戻る。 また最後まで読み、次のスペースに戻る 明確な文字列はスペース、[ 、]: のみ この文字列にはスペースが12個あるため、 これを12回繰り返す 上記の処理を明確に指定した文字列の数だけ行うため、 検索に時間がかかる。
正規表現と静的文字列 正規表現である以上、パフォーマンスへの影響は避けられないので、 入力パターンが限られている場合は静的文字列による検索を使う 10億文字の中から検索したときの処理時間を測定 静的な文字列で検索 正規表現で検索 「.*」を追加して検索 7/8
まとめ ・正規表現は様々な文字列パターンが想定される場合に活躍する ・より長く具体的な正規表現により、検索遅延を軽減できる ・入力パターンが決まっている場合は、正規表現の使用を避ける 8/8