正規表現
正規表現は、テキスト処理のスイス軍用万能ナイフです。 プログラマーは文字列をパターンでマッチさせ、さらにマッチしたものを、取り出す事ができるようになります。 正規表現の一番シンプルな例は、 文字や数字と==~オペレーターを使ったものです。 では、Dan Qualye氏のポテトのスペル'potatoe'でマッチを試してみましょう。(訳注:ダン・クエール Dan Qualye 1989年~93年 ブッシュ大統領の下で副大統領を務める。ポテトのミススペル potatoe で有名になったらしい。 正しいスペルは、potato です)
groovyコンソールで実行すると true と評価されます。注目点は、第1に==~オペレーターです。==オペレーターと似ていますが、equality の検査でなく、パターンマッチを行います。第2に正規表現が / に囲まれていることです。 / の囲みが groovy とコードの読み手にこの中は、単なる文字列でなく正規表現であることを伝えます。
正しいスペル potato もマッチさせたい場合は、'e'の後ろに'?'を付けます。以下は、依然として true と評価され:
正しいスペルもマッチします:
でも、その他では、マッチしません:
マッチしたかbooleanを返す簡単な正規表現でした。
もう少し進みましょう。 正規表現をテストするメソッドを書いてみましょう。 Pete Wisniewski という名前の ラストネーム Wisniewski でマッチさせるサンプルです。 (訳注:Pete Wisniewski が何者か不明)
新しい事が出てきました。 関数(function)です。(正確にはメソッドですが、私はこの2つの言葉を同じように使っています) 関数は、クロージャーに似た、コードの集まりです。 関数は常に名前があります。 一方はクロージャーには無名(anonymous)も可能です。 関数を定義すると後で何回でも使うことができます。
この関数の青地の if ステートメントでは、パラメーターのスペルをチェックしたい文字列と同じくパラメーターの正規表現がマッチするするか ==~ オペレーターでテストします。
さらに進みましょう。 文字列の真ん中の 'w' 文字がなくてもマッチしたい時:
スペルチェックの正規表現に追加された1個の ? は その直前の要素(ここでは 'w' 文字)が任意(あるか、ないかのどちらか)である事を現します。 変数 spellingAttempt に色々なスペルを入れて試してみましょう。 2つのスペルのみ通ることが分かります。 'Wisniewski' と 'Wisnieski' です。 (注:groovyコンソールの最初にcheckSpellingの定義を残しておいてくださいね)
この '?' は正規表現の世界で特別の意味をもった文字の一つです。
次に、チェック対象スペルの真ん中にある 'ie' という文字が逆順でも通るようにしてみます。 次のコードを見てみてください:
"Wisniewski", "Wisneiwski", "Wisnieski", "Wisneiski" の4つのスペルだけマッチします。 '|' 記号は、左側または右側のどちらかのみを許可します。ここでは "ie" または "ei" です。( ) かっこは、適用範囲を示します。
最後に紹介するおもしろい機能は、「キャラクタ(1文字)の集まりの中のどれかのキャラクタ(1文字)とマッチするかチェックする」です。 [ ] かっこを使います。 Peter さんのラストネームの色々な間違ったスペルでこの正規表現を試してみましょう。
最後の行は、説明が要りますね。 かぎかっこ [ ] 内の最初の文字は ^ ですが、これは、かっこ内の文字以外の一つの文字を現します。
オペレーター
ここまでで、正規表現がどう働くのかの感じがつかめたね。 以下はよく使う正規表現オペレターです。
正規表現オペレーター
a? |
0回 または 1回 *a* とマッチする |
'a' または 空文字 |
|---|---|---|
a* |
0回 または 1回以上 *a* とマッチする |
空文字または 'a', 'aa', 'aaa' など |
a+ |
1回 または 1回以上 *a* とマッチする |
'a', 'aa', 'aaa' など |
a|b |
*a* または *b* とマッチする |
'a' または 'b' |
. |
すべての1個のキャラクタとマッチする |
'a', 'q', 'l', '_', '+' など |
[woeirjsd] |
指定されたキャラクタのどれかとマッチする |
'w', 'o', 'e', 'i', 'r', 'j', 's', 'd' |
[1-9] |
指定範囲のどれかのキャラクタをマッチする |
'1', '2', '3', '4', '5', '6', '7', '8', '9' |
[^13579] |
指定されてキャラクタ以外とマッチする |
偶数の数字または、他の文字・記号キャラクタ |
(ie) |
グループを表現します (他のオペレターと一緒に使います |
'ie' |
^a |
行頭の *a* とマッチする |
'a' |
a$ |
行末の *a* とマッチする |
'a' |
覚えておく事。 上記のオペレーターをただのキャラクタとして扱いたい時(たとえば、クエッションマークをマッチしたい)は、前に'\'をおく必要があります。 例:
これは、醜い正規表現ですね。(Pealでの、このようなコードの多用が、Pealが書くためだけの言語といわれる理由の一つです)
ところでアンジョリーナ・ジョリーの身長は、googleで分かりますよ[she is|http://www.google.com/search?hl=en&q=how+tall+is+angelina+jolie&btnG=Google+Search]
このような正規表現の理解の仕方は、ばらばらにして見ることです。
/ |
[^?] |
+ |
? |
/ |
|---|---|---|---|---|
正規表現の始まり |
'?' 以外のキャラクタ |
1回以上の繰り返し |
クエッションマーク文字 |
正規表現の終わり |
? の前の \ が、クエッションマーク文字そのものを現す働きをします。