[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48. 正規表現とは (2007/12/06)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=regexp"
"MeadowMemo/正規表現とは"へのコメント(無し)
検索全文Elisp


普通,文字を検索するというと,単に「 emacs 」と単語を入力すると思います.

もちろん,これでも検索できますが,「 emacs 」という単語で始まる行を探したい時には 何度も移動する必要があり不便ですね.

そこで,正規表現というものがあります.これを使うと,「emacsで始まる行」や「emacs で始まりfunctionで終わる関数」などなど,様々な検索を行うことができるのです.

しかし,正規表現に慣れていないと,なかなか使うことができません.

そこで,このページでは正規表現の基礎について簡単に紹介していきます.合わせて,正 規表現に関連した Elisp なども紹介していきます.

ちなみに正規表現は「 regexp 」や「 re 」などとよく表現されます. Emacs Lisp の関数 でも「 regexp 」で終わる関数はたくさんあります.つまり,これを見たら「この仮数は 正規表現が使えるんだな」と考えることができるわけです.

また,この章で対象としているのは Meadow (Emacs) で使うことのできる正規表現です (ほとんどの項目は perl や Ruby などでもあまり変わりませんが,一部 Emacs 独特の記 法が含まれています).



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.1 正規表現での検索 (2005/03/28)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=search%20regexp"
"MeadowMemo/正規表現での検索"へのコメント(無し)
検索全文Elisp

正規表現を使って検索する代表的な方法として,インクリメン タルサーチ があります.

C-s による検索は,単語のみの検索ですが,C-u C-s として実行すると,正 規表現で検索できます.して,正規表現を入力する方法があります.

正規表現に馴染みのない方は,ぜひ,適当なバッファで練習してみてください.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.2 正規表現の書き方 (2005/03/28)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=start%20regexp"
"MeadowMemo/正規表現の書き方"へのコメント(無し)
検索全文Elisp

実際に正規表現とはどのようなものか,どう書くと目的とする単語を表現できるかをここ で説明していきます.

48.2.1 簡単な正規表現 (2005/03/28)  
48.2.2 指定した文字の繰り返し ― 正規表現 (2005/03/28)  



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.2.1 簡単な正規表現 (2005/03/28)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=regexp%20basic"
"MeadowMemo/簡単な正規表現"へのコメント(無し)
検索全文Elisp

正規表現と聞くと,何やら難しそうだなとか,複雑そうとか感じるかもしれません.しか し,基本的な正規表現はとても簡単です.ここで,その基本部分について説明しますので, ぜひチャレンジしてみてください.

まず,最も簡単な正規表現は「 a 」や「 e 」などです.

これは,冗談ではありません.実は,特殊な文字を除けば,すべての文字は正規表現なの です.何も難しく考える必要はないのです.

さて,これを少し発展させてみましょうか.

「 a+ 」はどんな文字に一致すると思いますか?

正規表現で「 + 」は「 + 」という文字には一致しません.代わりに「+」は特別な意味を 持つのです.「+」は「直前の文字の 1 回以上の繰り返し」を意味しています.だから, 「 a+ 」なら,「 aa 」,「 aa 」,「 aaa 」などに一致することになります.

では,少し変わって「 a*」はどうでしょうか.

これは,「 a という文字列の 0 回以上の繰り返し」を意味します.だから, 0 回.す なわち空文字 (何もない文字) にも一致します.C-u s a * でインクリメンタルサー チを実行してみてください.「a」や「aa」など以外の部分にもカーソルが移動すること を確認できます.

この空文字とは,何もない文字のことです.「 Emacs 」という言葉は別の言い方をすれば 「 E (空文字) macs 」や「 E (空文字) (空文字) macs 」ともいうことができます.そこ に何もない.それが空文字です.

これが何が便利なのでしょうか.例えば,「 setq 」と「 set 」という文字を検索した いとします.最後に「 q 」がつく保証は何もありません.つくかもしれませんが,つか ないかもしれません.こんな時には「 setq*」とすればいいのです.これで,「 setq 」 と「 set 」の両方に一致します.

これを「*」ではなく「 setq+ 」としてしまうと,「 setq 」や「 setqq 」,「 setqqq 」などに一致することになり,「 set 」には一致しません.

では,「 set 」と「 setq 」にだけ一致して,「 setqq 」には一致させたくない時には どうすればいいでしょうか.

これは,「 setq? 」と書きます.この「? 」は「 0 回か 1 回繰り返す」ことを意味して います.

ちなみに,こんな風に「その文字自身ではなく,何らかの意味を持つ文字」のことを「メ タキャラ」と呼びます.ここでの例では「 + 」や「*」,「? 」がメタキャラになります.

ここまで,読んでくると, 1 つ疑問が出てきませんか?

それはメタキャラである「 + 」や「*」はどうやって検索するんだろう,ということです ね.これらを検索するためにはその直前に「\」をつけて「\+ 」や「\*」とします.こう いう風にすると,「 + 」や「*」という文字に一致します.こうやって,「\」をつけて特 殊な文字ではなく,通常の文字とみなすようにすることを「エスケープする」あるいは 「クォートする」と言います.

ただし,「\」のように,エスケープすることのできる文字は環境やソフトによって違うの で注意が必要です. Meadow ならば「\」と思っていて問題ありません.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.2.2 指定した文字の繰り返し ― 正規表現 (2005/03/28)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=plus%20regexp"
"MeadowMemo/指定した文字の繰り返し―正規表現"へのコメント(無し)
検索全文Elisp

前で紹介した「 a+ 」は「 a 」なら「 a 」だけを繰り返すものでした.しかし,実際に は「 a だけではなく,他の文字も含んだ文字を検索したい」ということもよくあります (アルファベットのみからなる単語など).ここでは,そんな文字の検索方法を紹介します,

「.+ 」という正規表現があります.

この「. 」はメタキャラで,「改行以外の任意の 1 文字」を意味します.だから,「.+ 」は「改行以外の任意の 1 文字の 1 回以上の繰り返し」を意味します.要は一行全部で すね.

これをちょっと工夫して「 e.+s 」とすれば,「 e で始まり s で終わる文字」に一致し ます.

実際に例を見てみましょう.

emacs は 「 emacs makes a computer slow 」の略です.

の行頭で,C-u C-s e.+s としたら,どの範囲が一致するでしょうか.

答えは 「 emacs は 「 emacs makes a computer s 」までです.

一致箇所は,「 emacs 」までではないことに注意してください.正規表現では,一致する 箇所が複数あった場合,最も長い範囲に一致したと考えるようになっています.

つまり,「 emacs」に一致させるためには,もう一工夫が必要になります.

同じようにして「 e.*s 」でも,同様の検索はできます.ただし,これだと「 es 」にも 一致します.同様に,「 s で終わる文字」は「.*s 」あるいは「.+s 」です.この「. 」 はメタキャラなので,「. 」自身を検索する時には「\. 」のようにエスケープする必要が あります.

さて,この「. 」は任意の一文字に一致しますが,もっと絞りたい時もありますね.例え ば,「英字のみ」を表わしたい時にはどうすればいいでしょうか?

「 [a-z]+ 」とします.

これは,「a-zまでの英字のみを 1 回以上繰り返す」という正規表現です.この例の 「 [] 」はメタキャラで,「 [] の中にある文字の中のどれか 1 つ」を意味します.

そして,アルファベットの小文字のみなら, a から z までいちいち入力するのは面倒な ので,この例のように間を省略して「 a-z 」と書きます.同じように大文字なら「 A-Z 」,数字なら「 0-9 」と書くことができます.

だから,これら全部を検索したければ「 [a-zA-Z0-9]+ 」とすればいいわけです.

もっと絞り込みたい場合には「 [acems]+ 」とします.これだと「 a , c , e , m , s を 1 回以上繰り返したもの」に一致します.だから,「 a 」「 ac 」「 sc 」 「emacs」といった単語に一致します.

さて,では「 [] 」自身を繰り返しの候補としたい時にはどうすればいいのでしょう.こ れは簡単.「 [」は単に「 [」と入力すれば構いません.「] 」はちょっと面倒で 「 []a-z]+ 」のように先頭に置く必要があります.ついでに,「-」も「 [-a-z]+ 」のよ うに先頭に置く必要があります.

前章では,「 + 」や「*」,「. 」自身を検索するにはエスケープする必要があると書き ました.間違ってはいませんが,この「 [] 」ではちょっと異なります.例えば 「 [.a-z]+ 」とすると,「. と a-z までの文字を 1 回以上繰り返す」となります.エス ケープはしていませんが,「. 」が「. という文字」になるのです.



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.3 正規表現関連の Elisp (2003/03/12)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=regexp%20tools"
"MeadowMemo/正規表現関連のElisp"へのコメント(無し)
検索全文Elisp

ここでは正規表現に関連した Elisp などを紹介します,

48.3.1 正規表現の作成・確認 ― re-builder (2003/06/29)  



[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [表紙] [目次] [索引] [検索] [上端 / 下端] [?]

48.3.1 正規表現の作成・確認 ― re-builder (2003/06/29)

URL="http://www.bookshelf.jp/cgi-bin/goto.cgi?file=meadow&node=re-builder"
"MeadowMemo/正規表現の作成・確認―re-builder"へのコメント(無し)
検索全文Elisp

お勧め度:★★★★☆.正規表現を試す時には, isearch を利用したりしてましたが,こ んなものが用意されているとは知らなかった.正規表現を書く必要がある時には非常に便 利だと思います.

簡単な検索ならともかく,複雑な正規表現となると,これで本当にうまく検索できるのか不 安になりませんか?

そんな正規表現を実際に試すことができるものが, re-builder です.

標準で付属してますので,M-x re-builderとするだけで使うことができます.

これを実行すると,小さなウィンドウができて,そこへフォーカスが移動します.そして, 正規表現を入力すると,検索が実行され,一致したすべての文字には色がつきます.

また,正規表現が正しくないとモードラインに「*invalid*」と表示されます.こんな風 に,正規表現 のチェックや実際の結果確認ができます.

また入力用にウィンドウができるので,編集が簡単で, isearch などを利用するよりもずっ と簡単です.

キーバインドは以下の通り.

ただ,文字の色が白や灰色だとハイライト時に見えなくなってしまうので,

 
(eval-after-load "re-builder"
  '(progn
     (set-face-foreground 'reb-match-0 "black")
     (set-face-foreground 'reb-match-1 "black")
     (set-face-foreground 'reb-match-2 "black")
     (set-face-foreground 'reb-match-3 "black")
     ))

のように設定しておくといいです.


[ << ] [ >> ]           [表紙] [目次] [索引] [検索] [上端 / 下端] [?]