正規表現のススメ_20091217
TRANSCRIPT
正規表現のススメ
正規表現について
正規表現(せいきひょうげん、 regular expression )とは、文字列の集合を一つの文字列で表現する方法の一つである。正則表現(せいそくひょうげん)とも呼ばれ、形式言語理論の分野では比較的こちらの訳語の方が使われる。まれに正規式と呼ばれることもある。
(wikipedia: 正規表現 http://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE)
というお堅い説明ですがそれが嫌いな人向けの説明としては指定した、文字列 ( 数字含む ) の検索・置換等が楽になります。
ただパターンと呼ばれるマッチさせるための表記法が初心者にはとっつきにくい感はあり。
※ 正規表現にも色々ありますが、今回は Perl の場合においての正規表現として紹介します。
※PHP ユーザーも Perl 互換の関数 (preg 系 ) があるのでそれにも応用可能です。
エスケープシーケンス
\n 改行
\t タブコード
\a 内臓ベルを鳴らす ( 制御系コードの模様 )
\b バックスペース
\r キャリッジリターン ( 1)※
\z EOF( エンドオブファイル = ファイルの終端 )
\\ 、 \” 、 \’ それぞれ \ 、ダブルクォート、シングルクォートを表記
※1 キャリッジリターン Carriage Return(CR) = 改行位置と思ってください。MacOS ではこの CR で改行を表します。Windows ではラインフィード (LF = \n) とキャリッジリターンを組み合わせて改行を表します (\r\n) 。Unix 系ではラインフィードで改行を表します。
キャリッジとはタイプライター機器において文字を打ち込みつつ移動する部品の名称。これを元に戻す = 改行するということがあり、その名残らしい。
メタ文字 (1/2)
■ メタ文字・・・以下のような特殊な意味を持つ文字と思ってください
.( ピリオド ) 改行を除く任意の 1 文字
*( アスタリスク ) 0 回以上の連続する文字
+ 1 回以上の連続する文字
? 0 または 1 回だけの文字
^ 文字列の先頭。アクサンシルコンフレックスと読むらしい。べき乗記号と読んでました。「あいうえおあいうえお」とあるうち、「 ^あ」とした場合先頭の「あ」がマッチします。途中にある「あ」はマッチしません。
$ 文字列の末尾
|( パイプライン ) a|b|c ならば a もしくは b または c がマッチする。といったようないずれか(OR) を表す。
\ エスケープ文字。特殊な文字をマッチさせたい際に使用。+ をマッチさせたいが、メタ文字であるので・・・ \+ といったようにすればマッチする。
( ) グループ化。(aaa) とすれば、文字列中にある aaa がマッチ。
[ ] 文字クラス。 POSIX ブラケット表現とも呼ぶらしいです。任意の文字にマッチさせる文字の集合体と思ってください。お [父母兄姉 ]さんと表現した場合、「お父さん」「お母さん」「お兄さん」「お姉さん」のいずれにもマッチします。便利!
メタ文字 (2/2)
■ メタ文字・・・以下のような特殊な意味を持つ文字と思ってください
{n} 量指定子。 n は数値。aaa{3}
aaaa とあった場合、 aaa(3 つ ) がマッチする
\d 数字にマッチ。 [0-9] と同じ。
\D 数字以外にマッチ。 [^0-9] と同じ。
\w 英数字にマッチ。 [_a-zA-Z0-9] と同じ。
\W 英数字以外にマッチ。 [^_a-zA-Z0-9] と同じ。
\s 空白にマッチ。 [ \t\r] と同じ。
\S 空白以外にマッチ。 [^ \t\r] と同じ。
\b 単語の境界にマッチ。 \w もしくは \W の間。
\B 単語の境界以外にマッチ。
Tips(1/2)
■ 範囲指定文字クラス内に -( ハイフン ) を使用すると範囲が指定できます。
例 ) 01234 ~ 89 のいずれかにマッチ。文字列: 0123456789パターン: [0-9]
例 2)[a-z]文字列 :abcdefghijklmnopqrstuvwxyzパターン: abc ~ xyz のいずれかにマッチ。
例 3) abc と mno のいずれかにマッチ。文字列: abcdefghijklmnopqrstuvwxyz パターン: [a-cm-o]
■ 否定文字クラス文字列の先頭を表す ^ は文字クラス [] 内で使用すると、否定となります。
[^ マッチさせたくない文字 ][^0-9] = 数字 (0-9) 以外がマッチ
■n 回以上、 m 回以下にマッチ指定文字が n 回以上、 m 回以下のものをマッチ、といったことができます。{n,m}
例 ) dddd と eeeee のみがマッチ文字列: a bb ccc dddd eeeee パターン: \w{4,5}
Tips(2/2)
■ 行末の空白を表す\s+$\s = 空白、 + = 1 文字以上存在、 $ = 行末
これを使って行末に空白があった場合削除できます。逆に行頭にできたインデントやタブなどの空白を削除する場合^\s+^ = 行頭、 \s = 空白、 + = 1 文字以上存在
■ 肯定の後読み ( と呼ぶらしいです )
abcdef とあった場合のみマッチします。(?<=abc)def
abccdef 等の場合はマッチしません。
■ 否定の後読みaabef とあった場合等、 defの前に abcが無い場合のみマッチします。(?<!abc)def
abcdef = マッチしないbbdef = マッチする
※ 逆に肯定の先読み、否定の先読みといったようなものもあります。abc(?=def) = abc のあとに def がある場合マッチ ( 肯定の先読み )abc(?!def) = abc の後に def が無い場合マッチ ( 否定の先読み )
まとめ
正規表現を使えば、様々なパターンの言葉が来ても応用が利くようにできておりコードを何行も書く必要がなくなったりすることも多々あります。
ただ、正規表現に慣れていない人には理解し難いこともありコードが見難いといった弊害もあります。また同じ正規表現を表そうとしても人によってパターンが違う ( 方言と呼ぶらしい ?) がありますがそういうデメリットは些細なこと!と思えるほど便利なものなので是非使いまくると良いかと思います。
引用、参考元wikipedia:正規表現http://ja.wikipedia.org/wiki/%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE
サルにもわかる正規表現入門http://www.mnet.ne.jp/~nakama/
PHP正規表現チェッカー( 長い正規表現を書く場合等に使用する ? 正規表現シミュレーションみたいなもの )http://www.rider-n.sakura.ne.jp/regexp/regexp.php
正規表現アプレット (Java Applet)http://www.noids.net/applet/regex/index.htm