"Regular Expression" #8
Riue ちゃんの正規表現講座 / 其八
Perl の正規表現には、「\」付きの様々なメタキャラクタが存在します。
始めのうちはややこしく思えるかもしれませんが、いずれも強力なものなので、是非覚えて下さい。
前回、perl のルールとして、「普通の文字の直前に「\」がつくと、
その文字がメタキャラクタになってしまうコトがある」
ということを説明しました。そのときは「別に今すぐこの表を全部覚えろ、
というわけではありません」なんて書きましたが…。
私はウソつきです。Perl の第二回目は、前回出した表を全部覚えていただくことにしたいと思います。 最後に学校を卒業したのははやウン年前、なんていう貴女、今回はバリバリとメタキャラクタを覚えていただきましょうか… などと考えてたのですが、全部はちょっと大変なので、今回は半分くらいにしましょう。
空白とタブとビデオテープ
紙と鉛筆の世界から見ると、計算機の世界っていうのは「空白」まで文字と定義している… という点で、非常に奇妙に見えます。 「『文字』という高尚な概念に『空白文字』なんていう何処の馬の骨とも分からんものが入るとは何事だ!!」と、 日本のお父さんならずとも怒り出したくなるのではないでしょうか。 でも、計算機の世界にはデンとして「空白」というものが「文字」の姿を借りて存在しているわけですから、 空白とはきちんとしたお付き合いをしていかなければなりません。
| 文字名称 | ASCII | メタキャラクタ |
|---|---|---|
| スペース | 0x20 | (スペース) |
| タブ | 0x09 | \t |
| 改ページ | 0x0c | \f |
| 復帰 | 0x0d | \r |
| 改行 | 0x0a | \n |
ところで、一口に「クーハク」と言っても、世の中には様々な「空白」があります。 例えば、「スペース」と「タブ」は、見た目は空白でも文字コードは全く異なります。 Perl が「空白」として扱う文字は、こんな感じで 5 種類も存在します。それらを表に纏めてみました。
この表を見ておわかりの通り、各文字にはそれぞれ個別のメタキャラクタが割り当てられています。
例えば、タブにマッチするメタキャラクタは「\t」という感じですね。
ところで、Perl では便利なことに、これら 5 種類の空白文字を表すためのメタキャラクタというものを準備しています。 それが
\s
というメタキャラクタです。
もしこの文字がないとしたら、我々は「空白」という概念を表すために「[ \t\f\r\n]」
などという醜い表現を使わないといけなかったところでした。
「\s」の「s」とは、(多分)単純に「space」の「s」なのだと思います。
…そう言えば昔、こんなタイトルの SF 小説がありましたね。邦題は「ウ」でしたけど。
この「\s」、1 文字で全ての「空白」を表現できる大変便利なものなのですが、
一つだけ注意しなければならないことがあります。それは、
「\s」は空白文字 1 文字を表現する
という、ごく当たり前ことです。でもこれを忘れると、間違いなくとんでもない目に逢います。 例えば、「『Aldus』と『Adobe』という二つの単語が並んでいて、二つの単語は空白文字で区切られている」 (「Aldus Adobe」という感じですね)という状況を表現することを考えましょう。単純に、
Aldus\sAdobeと書いた場合、どうなるでしょうか。
この表現が意味するところは、「『Aldus』と『Adobe』の間には、空白文字が 1 つだけある」ということです。 ですから、「Aldus」と「Adobe」の間にスペースが一つだけ、 或いはタブ 1 文字だけであれば場合は問題ないのですが、「Aldus」と「Adobe」の間にスペースが 2 つあった場合、この正規表現では決してマッチしません。このようなことも考慮して、
Aldus\s+Adobe…つまり、「『Aldus』と『Adobe』の間には空白文字が 1 つ以上ある」と書くのが、正しい使い方というわけなのです。
通常の Perl を使う場合、「\s」は日本人にはお馴染みの所謂「全角スペース」にはマッチしません。気をつけて下さい。
(大抵の場合)大文字は逆さまの意味
Perl には「\s」の反対を意味する
\S
というメタキャラクタもあります。
「\s」の反対というわけですから、
「空白文字以外の 1 文字にマッチする」メタキャラクタになるわけですね。
ややこしく書くとすれば「[^ \t\f\r\n]」となるでしょう。
Perl におけるこの手のメタキャラクタでは、 「大文字の意味は小文字の意味の反対であることが多い」ということを覚えておいて下さい。
単語を構成する文字
さて、空白を表現するメタキャラクタがあるのですから、
一般の文字を表現するメタキャラクタがあっても良さそうなものですよね。
勿論「[a-zA-Z]」と書けばいいのですが…これって、かなり不恰好な気がしませんか。
Perl らしくスマートに事を運ぶには、このメタキャラクタを使いましょう。
\w
「\w」は「『単語』を構成する
1 文字」にマッチするメタキャラクタです。「『単語』を構成する
1 文字」とは、具体的には「『英数字』と『_(アンダーライン)』」のことです。
つまり、「[0-9a-zA-Z_]」という意味になります。
この「\w」、「『単語』を構成する 1 文字」にマッチするだけであって、
「『単語』にマッチするわけではない」ということに気をつけて下さい。
単語にマッチさせようとした場合は、当然「\w+」と書く必要があります。
「\w」があるということは、勿論
\W
もあります。これは「単語を構成する文字以外」にマッチするメタキャラクタ…
つまり、「[^0-9a-zA-Z_]」という意味です。
ところで、ついでですから「数字 1 文字にマッチするメタキャラクタ」もここで紹介しておきましょう。
\d
「\d」は「数字1文字にマッチするメタキャラクタ」です。
つまり「[0-9]」と同じですね。
逆に、「数字以外の文字にマッチするメタキャラクタ」、つまり「[^0-9]」
を意味するメタキャラクタは、皆様の予想通り
\Dです。
「\w」の「w」は、やはり単純に「word」の「w」でいいのだと思います。
「\d」の「d」は、「digit」の「d」なのでしょうね。
ところで、「\w」
がマッチする文字の中に、「_(アンダーライン)」が入っているのは意外かもしれません。
つまり、「\w+」という正規表現は
「this_is_a_very_long_word」なんていう「単語」にもマッチしてしますので、この点には気をつけて下さい。
一般人には縁がないモノ
普通の人は、今までに紹介したメタキャラクタが使えれば十分だと思います。 これからご紹介するのは、プログラマ様とか計算機屋様と言った「非一般人」向けのものになります (いや、一般人兼プログラマという方もおられるかもしれませんが…)。 というわけで「ボクちゃん一般人だから…」という人は、次の節まで飛ばして下さっても構いません。
\011-
「
\」に続けて 2 桁または 3 桁の数値を書いた場合…これは文字を 8 進数で表現したものとして扱われます。 この例では、「タブ」にマッチします(ここで、2 桁の表記で「\11」と書いても、勿論大丈夫です)。 \x41-
「
\」の直後に「x」があり、それに 2 桁の数値が続く場合…これは文字を 16 進数で表現したものとして扱われます。この例では、「A」という文字にマッチします。 \cD-
「
\」の直後に「c」があり、それに 1 文字が続くものは、対応する「Ctrl + 文字」にマッチします。この例では、「Ctrl-D(^D)」にマッチすることになりますね。 \a-
ベル(BEL)文字にマッチします。「
\cG」と同じです。 \e- エスケープ(ESC)文字にマッチします。
メタキャラクタと文字クラス
今までの例の中で、「\t」や「\r」という文字を「[]」の中に入れている…ということにお気付きでしょうか。
基本的に、ここで紹介したメタキャラクタは「[]」の構成要素として使用しても大丈夫です。
とは言え、「範囲を指定する」場合には使えないことがありますから注意して下さい。
例えば、「[\s-\w]」というような世紀末的正規表現は意味を成しません
(意味を考えれば考えるほど、無意味に思えるか混乱するか、じゃないですか?
この「[\s-\w]」という表現は)。
ところで、「[\s]」が有効な正規表現だとすると、
「『\』という文字と、『s』という文字のどちらか」というものを表現する場合、どうすれば良いのでしょう。
このような場合は「[\\s]」か「[s\\]」を使います。
但し、「[s\]」は使えません。
この場合、文字クラスを表現する「[]」の
「]」の文字がクォートされてしまい、エラーになってしまいますから。
とりあえずのおしまい
Perl の正規表現第 2 回目は、 とにかくメタキャラクタを覚えることに終始していただきました。 今まで限定正規表現や拡張正規表現で覚えてきた記法で代用できるメタキャラクタもありますが、Perl 独自のメタキャラクタを使うと「正規表現が読みやすくなる」 「タイプ数が減る」といった、ちょっとした恩恵にあずかることが出来ますし、 何となく「ああ、俺様ちゃんってば今 Perl を使ってるんだねぇ…」などという、 ちょっと訳分からない感慨に耽ることも出来ます。是非これらのメタキャラクタを使ってみて下さい。
それでは、次回までさようなら。