強火で進め

このブログではプログラム関連の記事を中心に書いてます。

Google Toolbox for Macの正規表現を使ってみた

Google Toolbox for Macの正規表現を使ってみました。

前回と同様、ウィンドウにボタンを配置し、アクションに以下の様なプログラムを設定しました。

#import "AppController.h"
#import "GoogleToolboxForMac/GTMRegex.h"


@implementation AppController

- (IBAction)run:(id)sender
{
    NSString *str;
    GTMRegex* regex;
    NSArray* array;
    
    // 正規表現に使用する文字列をエスケープ
    NSLog(@"--escapedPatternForString:");
    str = [NSString stringWithString:@"^.[$()|*+?{\\"];
    NSLog(@"%@", [GTMRegex escapedPatternForString:str]);

    // 0番目にマッチした文字列全体。以降はサブパターンにマッチした文字列を返す。
    // マッチしていない場合は NSNull となる。
    NSLog(@"--subPatternsOfString:");
    regex = [GTMRegex regexWithPattern:@"(fo(o+))((bar)|(baz))"];
    array = [regex subPatternsOfString:@"foooooobaz"];
    int num = 0;
    for (NSString *match in array) {
        NSLog(@"%d: %@", num++, match);
    }
    // 0: "foooooobaz" -> マッチした文字列全体
    // 1: "foooooo"    -> (fo(o+)) にマッチした文字列
    // 2: "ooooo"      -> (o+) にマッチした文字列
    // 3: "baz"        -> ((bar)|(baz)) にマッチした文字列
    // 4: NSNull       -> (bar) にマッチした文字列
    // 5: "baz"        -> (baz) にマッチした文字列

    // 最初にマッチしたものを返す
    NSLog(@"--firstSubStringMatchedInString:");
    regex = [GTMRegex regexWithPattern:@"foo.bar"];
    NSLog(@"%@", [regex firstSubStringMatchedInString:@"foo1barfoo2barfoo3bar"]);

    // マッチしたかをBOOLで返す
    NSLog(@"--matchesSubStringInString:");
    regex = [GTMRegex regexWithPattern:@"foo.bar"];
    NSLog(@"%d", [regex matchesSubStringInString:@"foo1bar"]);
    NSLog(@"%d", [regex matchesSubStringInString:@"foo123bar"]);
    
    // マッチした文字列を置き換え
    NSLog(@"--stringByReplacingMatchesInString:withReplacement:");
    regex = [GTMRegex regexWithPattern:@"(foo)(.*)(bar)"];
    NSLog(@"%@", [regex stringByReplacingMatchesInString:@"foo123bar"
                            withReplacement:@"<b>\\2</b>"]);
    
    // NSStringにカテゴリが定義してあるため、NSString でも今までに紹介したメソッドと
    // 同様な処理が可能になっています
    // ※NSString のデータはパターンの文字列ではなく、検索対象の文字列になるため多少
    //  引数が異なることに注意
    NSLog(@"--gtm_stringByReplacingMatchesOfPattern:withReplacement:");
    str = [NSString stringWithString:@"foo123bar"];
    NSLog(@"%@", [str gtm_stringByReplacingMatchesOfPattern:@"(foo)(.*)(bar)"
                                            withReplacement:@"<b>\\2</b>"]);
}

@end

出力結果はこうなります。

--escapedPatternForString:
\^\.\[\$\(\)\|\*\+\?\{\\
--subPatternsOfString:
0: foooooobaz
1: foooooo
2: ooooo
3: baz
4: <null>
5: baz
--firstSubStringMatchedInString:
foo1bar
--matchesSubStringInString:
1
0
--stringByReplacingMatchesInString:withReplacement:
<b>123</b>
--gtm_stringByReplacingMatchesOfPattern:withReplacement:
<b>123</b>

また、正規表現をどのように処理しているのかプログラムを確認したところ内部的には regexec() という関数を呼んでいました。

この関数、今まで知らなかったんですが調べたところC言語で正規表現を行う関数でした。Googleが自前で作ってたりするのかなぁ?と思ってたのでちょっと残念でした。

Manpage of REGEX
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/regex.3.html

フレームワークのプログラム内で REG_EXTENDED がセットしてあるため正規表現としては「POSIX 拡張正規表現」が使えるようです。

そのためPerlレベルの凝った正規表現は無理ですがちょっとした正規表現が必要なときなどには便利に使えそうです。

ちなみに正規表現についてこちらの本などが評判良いです。

詳説 正規表現 第3版

詳説 正規表現 第3版

でもまぁ、自分は難易度高そうなのでこっち使ってるんですけどw
正規表現の良く使うパターンの例題が載っていて実践にすぐ使えて便利です。
後、各種環境や言語別の方言について載っているのが良かったです。
正規表現ハンドブック (Technical Handbook Series)

正規表現ハンドブック (Technical Handbook Series)

Google Toolbox for Macの解説記事一覧はこちら