株式会社antsのホームページへようこそ。

初心者のための正規表現入門<第2回>

0
Posted in Lab. By nishihira

こんにちは。
「初心者のための正規表現入門」連載2回目の今回はいよいよ、いろいろな正規表現の文法を使ってみましょう。

正規表現はさまざまな言語や環境で使うことができますが、
今回の連載ではJavaScriptを使って実際のコーディングを行うことにします。

実際のコーディング例を見ながら一歩ずつ学習を進めて行きましょう。

はじめに:効率の良いテスト方法

複雑な正規表現を書くときは、実際にテスト実行してみないと意図した通りの正規表現が書けたかどうか分らないことが多いです。
なので、正規表現による検索・置換がリアルタイムにテストできるツールがあると効率が上がります。

一例として、以下のものを上げておきます。
これらはWebアプリなので、ブラウザ一つあれば正規表現のテストができるので便利です。

http://www.rexv.org/ (JavaScript,PHP用)
http://regexlib.com/RETester.aspx (.NET Framework用)

シンプルなマッチング(検索)と置換

■マッチング(検索)

正規表現による検索を行う場合は、文字列オブジェクトのmatchメソッドを使います。(*1)
メソッドの引数として、検索条件となる文字列を渡します。
文字列は、「/」(スラッシュ)で括ります。
if文の中でこのメソッドを使い、判定を行うのがもっとも簡単なやり方です。

*1. 実は、もっと処理効率の良い他の方法もあります。次回以降の連載で解説する予定です。

ソース1

var text = "クライアントPCのOSは、Microsoft Windows 2000です。";
if(text.match(/Windows/)){
  alert("あなたはWindowsユーザーです"); // 検索対象文字列が見つかった場合
}else{
  alert("あなたはWindowsユーザーではありません"); // 見つからなかった場合
}

■置換

正規表現による置換を行う場合は、文字列オブジェクトのreplaceメソッドを使います。
メソッドの引数として、置換対象となる文字列と、置換後の文字列を渡します。
検索と同じく、対象文字列は「/」(スラッシュ)で括ります。

ソース2

var text = "クライアントPCのOSは、Microsoft Windows 2000です。";
replaceText = text.replace(/Microsoft Windows 2000/,"Microsoft Windows Vista");
alert(replaceText);

特殊文字を使ったマッチング・置換

上記の例では、検索条件となる文字(列)そのものにしかマッチしませんでした。
ですが実際のプログラムの中では、もう少し複雑なマッチングが必要になるかと思います。
たとえばHTMLの入力フォーム(テキストフィールド等)で、入力値チェックを行う場合を例に考えてみましょう。

■チェック1:メールアドレス欄の入力チェック

・メールアドレスには、「@」が入っていなければならないものとする。

・また、「@」の両側には必ず文字が入っていなければいけない(「@」で始まったり終わったりしていたらエラー)

このチェックは、正規表現を使うと以下のように書くことができます。

ソース3

<input type="text" name="field_email">
<script>
<!--
var text = field_email.value;
if(text.match(/.+@.+/)){
  alert("正しいメールアドレスです"); // チェックOK
}else{
  alert("不正なメールアドレスです"); // チェックNG
}
//-->

正規表現の中で「.」と「+」という文字が出てきましたが、これらの文字は正規表現の中では特殊な意味を持っています。「.」は、「何らかの文字列1文字にマッチする」という意味になります。
「+」は、「直前の文字を1回以上繰り返す」という意味になります。
つまり上記の正規表現は「何らかの文字列が1文字以上、次に「@」、その次に何らかの文字列が1文字以上」という全ての文字にマッチすることになります。

この「.」「+」のような、特別な意味を持った文字を「特殊文字」あるいは「メタ文字(メタキャラクタ)」と呼びます。(ちなみに「@」は特殊文字ではなく、普通の文字です)
「+」によく似た特殊文字として「*」というのもあります。
「*」は、「直前の文字を0回以上繰り返す」という意味になります。
上記の正規表現を「/.*@.*/」と変えた場合は、「@」の前後の文字列が0文字でもマッチングするようになります。

■チェック2:郵便番号欄の入力チェック

・「3桁の数字」の後に「-」が続き、その後が「4桁の数字」で終わっている場合のみOK、ほかはエラーとする

このチェックは、正規表現を使うと以下のように書くことができます。

ソース4

<input type="text" name="field_postcd">
<script>
<!--
var text = field_postcd.value;
if(text.match(/^\d\d\d-\d\d\d\d$/)){
  alert("正しい郵便番号です"); // チェックOK
}else{
  alert("不正な郵便番号です"); // チェックNG
}
//-->

「\d」は「1文字の数字文字」を表す特殊文字です。
したがって「\d\d\d」は3桁の数字全てにマッチングします。
「-」は特殊文字ではない普通の文字なので、「\d\d\d-\d\d\d\d」という正規表現は
「3桁の数値」「-」「4桁の数値」という文字列にマッチングします。

「^」と「$」も特殊文字です。
「^」は文字列の始点を、「$」は文字列の終点を表します。
つまり「^」「$」をつけることで、「\d\d\d-\d\d\d\d」の前後に何も文字がないときだけマッチングするようになります。
(「^」や「$」は、単独で使うこともできます。)

大文字小文字の違いを無視したい場合

■チェック3:「ご利用のパソコンのOS」欄の入力チェック

・入力値に「Windows」が含まれるかどうかをチェックし、含まれていたら特別な処理を行う

ソース5

<input type="text" name="field_os">
<script>
<!--
var text = field_os.value;
if(text.match(/Windows/)){
  // OSがWindowsの時の処理
}else{
  // OSがWindows以外の時の処理
}
//-->

上記の例で、入力した文字が「windows」や「WINDOWS」だった場合は、
判定結果はfalseになり、「OSがWindowsの時の処理」は行われません。
正規表現は大文字と小文字とを区別するので、厳密に「Windows」と入力しないとマッチしないのです。
では、あえて大文字と小文字を区別しないようにはできないのでしょうか?
できます。その場合は以下のように書きます。

ソース6

if(text.match(/windows/i)){
  :
}

マッチング対象となる文字列「/windows/」の後に「i」を付けたのがポイントです。
これで「windows」はもちろん、「Windows」や「WINDOWS」にもマッチングするようになります。
このように、オプションとして「i」というフラグを付けることで大文字小文字の違いを無視してくれるようになります。

選択肢のうちいずれかにマッチすればOKとしたい場合

応用として、Windows2000とWindowsXPだけにマッチングするようにしてみましょう。

ソース7

if(text.match(/.+windows\s*(2000|XP)/i)){ //「microsoft windows 2000」「WINDOWS2000」「Microsoft-Windows XP SP2」全てOK
  :
}

またいくつか新たな特殊文字が出てきました。
「\s」は「\d」と似ていて、スペースやタブなどの空白文字の1文字にマッチします。
「(2000|XP)」は「2000」または「XP」という文字列、という意味になります。
もし「(2000|XP|Vista)」とした場合は、「2000」「XP」「Vista」どれでもマッチすることになります。

つまり上記の例は、「まず一文字以上の何らかの文字があり、次に『windows』という文字列が続き、その後0文字以上の空白文字、次に「2000」または「XP」どちらかの文字列が続く。
英文字をチェックするときは大文字小文字の違いは無視する」
という意味になります。

次回予告

いかがでしたでしょうか?
ぱっと見は難しそうに見える特殊文字ですが、一つ一つ使い方を見ていくと意外と簡単に思えたのではないでしょうか。
しかしこれらを組み合わせて使うことで、複雑なマッチング処理をたった一行の正規表現で行えるようになりますので、
ぜひいろいろと応用してみて下さい。

次回は、より高度なマッチング・置換を行うために必要な、いくつかの概念についてご説明します。
また、正規表現を使う場合のJavaScriptのコーディングに関する話題もいくつかお話しする予定です。
お楽しみに!