class: title, smokescreen, shelf, no-footer # 正規表現で正しい入力だけを読み込む <div class=footnote> <small> Copyright 2022 (C) Ken'ichi Fukamachi (<A HREF=https://www.fml.org/>fml.org</A>), CC BY-NC-SA </small> </div class=footnote> --- class: compact # 正規表現 <div class=footnote> <small> <B>Perlといえば正規表現</B>(regular expression 略して regexp), 他の言語でも使うし、多くの言語がPerlリスペクト </small> </div class=footnote> - ひとつながりの文字列を指定する方法で検索パターンとして多用されます - 応用 - 編集中のドキュメント内での検索 - OS上でその文字を含むファイルを探す(grep), 特定の名前のファイルを探す(find) - スペリングの間違いを直したいとき、ファイル群を一斉置換できる(sed) ``` sed -i s/pearl/perl/ *.txt ``` - 入力できる文字を限定する(input validation) - 例: こういった文字のパターンを指定する方法 - 数字だけ e.g. 1, 100, 900000 - 学籍番号 e.g. bの後に数字が7個つづく - アルファベットと数字だけで最低16文字(パスワード) --- class: compact # 例題: 学籍番号b2902900のような表現? 1. bのあとに数字が1個以上つづく 1. bのあとに数字が7桁 1. 先頭はbでもBでもよくて、そのあとに数字が7桁 1. 先頭はアルファベット(文字数不定)で数字がつづく(桁数不定) <div class=footnote> <small> いったん公式テキストへすすめ </small> </div class=footnote> --- class: compact # 解答: 学籍番号b2902900のような表現? <div class=footnote> <small> (注意) 正規表現による検索は文章の一部がマッチするだけでもtrueになります。 これでは「b2902900」「学籍番号b2902900の人は再試です」どちらの文章もマッチします。 これでは入力チェックにならないよね? <br> よって「入力が学籍番号になっているか?」の表現は 2 or 3 が半分だけ正解です。では、<B>正しくは何でしょう?</B> <br> なお正解が 2 or 3 なのは「大文字と小文字を区別する/しない」は仕様しだいだから </small> </div class=footnote> 1. bのあとに数字が1個以上つづく - `b\d+` 1. bのあとに数字が7桁 - `b\d{7}` 1. 先頭はbでもBでもよくて、そのあとに数字が7桁 - `[bB]\d{7}` - Perlでは`/b\d{7}/i`のように書ける <br> (case **i**nsensitive, **大文字小文字を区別しない**オプション) 1. 先頭はアルファベット(文字数不定)で数字がつづく(桁数不定) - `\w+\d+` --- class: compact # 課題 1. じゃんけんプログラムで、正しい入力だけを受け入れてください 1. もぐらたたきでも、正しい入力だけを受け入れてください 仕様を考えてください、受け付けるべき文字は何と何ですか? -> 正規表現 ``` // 書き方(擬似コード) ループ { my $input = ... ; // キーボードからの入力を$inputへ代入 chomp $input; // ENTER(改行コード)の分を削除 if ($input =~ /正規表現/) { next; // 選択肢1: ループの先頭へジャンプ(リトライ,次の入力待ち) last: // 選択肢2: ループ自体を終える(入力間違いは許さない) } } ``` --- class: col-2,compact # コラム: 正規表現の実装と歴史的うんちく <div class=footnote> <small> Ken Thompson は Unix, C言語, UTF-8, Go言語の(共同)作者 </small> </div class=footnote> - C言語 ... C言語ベースのプログラムでは、 これらを組み込んで正規表現サポートを実現しています - regexp(regcompなどの関数群) ... Unix clone では80年代に Henry Spencer の書いた V8 (互換)エンジンが大元 - pcre (Perl-compatible regular expressions) ... Perlの正規表現を実現するライブラリ(1997-)で、 Perl本家とは別に開発されています。 <wbr> - Perl - 正規表現に多くの拡張を加えました - しかも猛烈に高速な処理を行えます - テキスト処理ならPerlの原動力(ok?) - 正規表現 - 本来は形式言語という言語の文法や意味の数学的とり扱いの話 - 歴史上の重要な転回点は Ken Thompson が Unix のエディタ(ed)の中に組み込み、 正規表現を検索で使えるようにしたことです。 これ以降、 数学理論ではなく実用的なテクニックとして重要になりました