2006 年 7 月 29 日 22 時 42 分

正規表現


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


今日は、昨日と同じ処理を、正規表現を使ってやってみよう。

indexOf による探索は、速度面では速いのだが、
単純な文字列のマッチングしかできなく柔軟性に欠ける。
正規表現は、表現を作るのに若干の知識が必要だが、
文字列の処理を柔軟に行うことができる。

========== Main.js ==========

function main() {

    // ログイン
    var session = new MixiSession(
            "自分のメールアドレス", "パスワード");

    // 日記一覧ページの HTML を取得
    var html = session.fetch("http://mixi.jp/list_diary.pl");

    // 日記の正規表現
    var rexEntry = new RegExp(
            "<font COLOR=#996600>(.*?)<br>(.*?)</font>"
            + "[\\w\\W]*?"
            + "<td bgcolor=#F2DDB7> ([\\w\\W]*?)</td>"
            + "[\\w\\W]*?"
            + "<td CLASS=h120>\n([\\w\\W]*?)\n<br>\n\n</td>", "ig");

    for (;;) {

        var match = rexEntry.exec(html);
        if (match == null) break;

        WScript.Echo("================================");
        WScript.Echo("日時: " + match[1] + " " + match[2]);
        WScript.Echo("タイトル: " + match[3]);
        WScript.Echo("--------------------------------");
        WScript.Echo(match[4]);
        WScript.Echo("================================");

    }

}

mail();

========== end of Main.js ==========

正規表現のお陰でかなり短くなった。

JavaScript における正規表現は、
RegExp 型のオブジェクトとして表現される。

    var rex = new RegExp("パターン", "フラグ");
    var rex = new RegExp("\\b\var\\b", "i");

メタキャラクタ「\b」は単語境界に一致するため、
このパターンは、単語 VAR、vAr、Var などに一致する。
正規表現にはリテラル表記もある。
こちらは Perl に慣れている人にはお馴染みの構文だ。

    var rex = /パターン/フラグ;
    var rex = /\bvar\b/i;

後者の構文の場合、\ で始まるメタキャラクタは、
そのまま表記することができるが、
前者の構文の場合、表現は文字列として渡されるので、
\ は文字列リテラルのエスケープとして機能してしまう。
そのため、正規表現に \ を渡すためには、
\\ と 2 重に指定する必要がある。

正規表現の部分を見てみよう。

    "<font COLOR=#996600>(.*?)<br>(.*?)</font>"
    + "[\\w\\W]*?"
    + "<td bgcolor=#F2DDB7> ([\\w\\W]*?)</td>"
    + "[\\w\\W]*?"
    + "<td CLASS=h120>\n([\\w\\W]*?)\n<br>\n\n</td>"

日付、時間、タイトル、日記要約は、
(~) によるキャプチャで抜き出すことにした。

. は、改行文字に一致しないので、
[\w\W] という文字クラスによる指定を使っている。
\w は単語要素、\W は単語要素以外に一致するので、
[\w\W] はあらゆる文字に一致するということになる。

正規表現にはいくつもの書き方があるので、
上はあくまでも一例に過ぎない。
速度や効率を考えれば違う書き方もできるが、
面倒なので、簡単な表現を使うことにした。

さて、正規表現オブジェクトが完成したら、
exec メソッドを呼んで一致するか試す。

exec は、正規表現に一致した場合配列を返す。
一致しなかった場合は、null を返す。
ここでは、戻り値を match という変数に格納している。

match[0] は、正規表現が一致した部分の文字列である。
match[1] は、1 番目のキャプチャの内容で、日付だ。
match[2] は、2 番目のキャプチャの内容で、時刻だ。

match[1]~match[4] に必要な文字列が格納されているので、
昨日と同じように、WScript.Echo() で表示する。

因みに、match は、index、input というプロパティも持つ。
index は、正規表現が一致した位置を格納している。
input は、exec を呼び出した入力文字列が格納されている。

今回は、これらプロパティは使わないが、
正規表現を使う上で、覚えておけば便利である。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.