正規表現


正規表現とは

正規表現とは、1956年にアメリカの数学者「Stephen Kleene」氏が『Representation of Events in Nerve Nets』を著述し
そこで初めて正規表現の概念を紹介しました
ここで「正則集合の代数」を説明するのに使用された式が「正規表現」です

その後、この正規表現の概念はUNIXの中心的な考案者Ken Thompson氏によって
コンピュータでの検索アルゴリズムに引き継がれました
正規表現を初めて使用した実用的なアプリケーションは UNIX のエディタ qed です

					Microsoft JScript 5.5ドキュメント「正規表現の概説」参照
早い話が、現代における文字列操作や検索アルゴリズムの中心的存在ということです
これを利用しない手はありません

正規表現を用いれば、容易に検索対象に指定文字列が存在するか否かを確認できます
Perl言語がUNIXのテキスト処理言語として誕生し、文字列操作が得意といわれる理由がここにあります

正規表現は / / 記号で指定検索文字列を囲みます
たとえば /吉井さん/ とすれば、対象から「吉井さん」という文字列を探します
=~演算子を用いた場合、対象に文字列が存在すれば真を返します
!~演算子ならば、対象に文字列がなかった場合に真を返します
	$str = "Microsoft";
	print "指定文字列を発見しました\n" if ($str =~ /soft/);
	print "指定文字列は存在しません\n" if ($str !~ /Micro/);
このプログラムでは$strに格納されているMicrosoftという文字列を検索対象としています
2行目の =~ は指定文字列 /soft/ が検索対象に存在すれば真を返してprintに指定された文字列を出力します
3行目は2行目の反対で、 /Micro/ が検索対象に存在しなければ真を返します

以上が正規表現の基礎的な部分です
しかし、正規表現ではさらに高度な検索技術が多数存在します

検索文字列や検索された文字列に対して、さらに高度な操作をするには特殊変数を使います
$&変数には一致した文字列が代入されます
$`変数には一致文字列より以前の文字列がすべて代入されます
$'変数には、一致した文字列意向の文字列が代入されます

では、以下のプログラムを作成して正規表現をより詳しく調べてみましょう
	$str = "THE YELLOW MONKEY";

	print "検索する文字列を入力してください\n";
	$reg = <STDIN>;
	chomp($reg);

	if ($str =~ /$reg/) {
		print "\n文字列が確認されました\n";
		print "検索文字列 \n{" . $& ."}\n\n";
		print "検索文字列以下の文字列\n{" . $` ."}\n\n";
		print "検索文字列以降の文字列\n{" . $' ."}";
		}
	else {
		print "検索対象に指定文字列はありません";
		}
検索対象となる文字列は 【THE YELLOW MONKEY】 です
いろんな検索をして、どのような場合に一致するのか、特殊変数になにが代入されるかを試してください


オプション

/ /の後に、用意されているオプションキーワードを指定することで、より精密な検索が可能です
オプションは g , i , oの3つが存在し、これを指定することでさらに詳しい検索ができます

まず、gオプションから説明したいと思います
オプションを指定しなかった場合、検索文字列が一致すると以降検索されません
この場合、対象に指定文字列が何個存在するか、といった検索ができません

gオプションは、対象と指定文字列が一致した後も検索を続けます
そのためループによる検索時に非常に役に立ちます
たとえば、ディカプリオ様が主演の「仮面の男」の英タイトルは「THE MAN IN THE IRON MASK」です
THEが二つありますね、この二つのTHEを検出したい場合などに使います
	$str = "THE MAN IN THE IRON MASK";

	print "検索する文字列を入力してください\n";
	$reg = <STDIN>;
	chomp($reg);

	while ($str =~ /$reg/g) {
		print "\n文字列が確認されました\n";
		print "検索文字列 \n{" . $& ."}\n\n";
		print "検索文字列以下の文字列\n{" . $` ."}\n\n";
		print "検索文字列以降の文字列\n{" . $' ."}\n";
		}
	print "検索対象に指定文字列はありません" if ($str !~ /$reg/);
while ($str =~ /$reg/g) { に注目してください
whileは真の間くり返すという制御文でしたね、つまり文字列が一致する間繰り返します
最初のTHEが検出された後も、オプションgによって次の文字列から再び検索されIN THE IRONのTHEが検出されます


つぎにiオプションですが、これは特に多用しそうなので覚えて置いてください
たとえばCGIプログラムの検索エンジンをよく見かけますが、基本的に大文字と小文字を区別しないですよね

私たちが先ほどまで作っていた検索プログラムは、大文字と小文字を区別されていました
つまり、THE YELLOW MONKEY という文字列に対して yellow monkey という文字列を探しても一致しません
もうおわかりでしょうけど、iオプションは大文字と小文字の区別をなくします
	$str = "THE MAN IN THE IRON MASK";

	print "検索する文字列を入力してください\n";
	$reg = <STDIN>
	chomp($reg);

	if ($str =~ /$reg/i) {
		print "\n文字列が確認されました\n";
		print "検索文字列 \n{" . $& ."}\n\n";
		print "検索文字列以下の文字列\n{" . $` ."}\n\n";
		print "検索文字列以降の文字列\n{" . $' ."}\n";
		}
	else {
		print "検索対象に指定文字列はありません";
		}
最後の o オプションですが、これは変数の参照を最初だけ行うというものです
つまり、正規表現で変数が使われてる場合で g オプションで繰り返すときに、最初の一回目だけ変数を展開します
その後は展開された状態を使って検索を行なうようです


正規表現文字

さらに、Perl言語の正規表現ではより細かい検索ができる正規表現文字があります
これを / / の中で検索文字列として指定することで特殊文字の検索や検索文字列のマクロ化ができます
	$str = "kitty on your lap";

	print "検索する先頭文字列を入力してください\n";
	$reg = <STDIN>;
	chomp($reg);

	if ($str =~ /^$reg/) {
		print "\n文字列が確認されました\n";
		}
	else {
		print "検索対象の先頭に指定文字列はありません";
		}
たとえば、~ は指定検索文字列が対象の先頭と同じであれば一致したとみなします
たとえ文字列が存在しても、先頭文字列でなければ不一致であるとします

このような使用法で使える便利な正規表現文字は、他にもいくつかあります
詳しくは「正規表現文字一覧」を参照してください

検索優先順位は以下のようになります
↓高い↓
( )
? , + , * , { }
str(文字列) , ^ , $
|
↑低い↑


文字列を入れ替える

最後に、これまでは文字列の検索のみを行なってきましたが
今度は一致した文字列を指定文字列に変換するというプログラムを作りましょう

他言語を経験したことがあるプログラマさんは、この作業が初心者にはかなり労力を使うことをご存知だと思います
しかしPerl言語は正規表現を用いて先ほどの応用程度でそれを可能にします

書式はいたって簡単です。正規表現の前にs演算子を用います

s/検索文字/置換文字/[オプション]

これを指定すれば、検索された文字列部分をを置換文字に変換します
たとえば、オラという文字列を検索して、オラを「無駄」に変換したいならば
$str =~ s/オラ/無駄/
とします。オプションは通常の正規表現同様 g , i ,o を使うことができます

以下のプログラムは、入力された文字列の末尾に「にゃん」をつけて出力する「自動猫語変換機」です(^^;
	while ($reg ne "\n") {
		$reg = <STDIN>;
		$reg =~ s/\n/にゃん\n/;
		print $reg;
		last if ($reg =~ /exit/i);
	}
exitと入力すれば、プログラムを終了することができます

文字列変換の場合は eオプション というのもあります
eオプションは指定したの計算結果を変換させることができます



前のページへ戻る次のページへ