« 2013年10月 | トップページ | 2013年12月 »

2013年11月

2013年11月23日 (土)

Delphiで正規表現(Onigumo)

パクりシリーズの第3弾です。鬼雲版です。鬼雲 (Onigumo)というのは鬼車 (Oniguruma)を改良したエンジン(Oniguruma-mod)とのことで、Ruby 2.0の正規表現エンジンとして使われているそうです。まぁ、自分としてはどちらでも良かったので、最初は鬼車を使う前提でしたが、64bit環境でビルドすると、64ビットから32ビットへの縮小変換の警告??が大量に出るので、鬼雲を使うことにしました。こちらの方はヘッダファイルを見ると、64bit環境も考慮してるようです。

ということで、RegExPackを更新しておきました。

まず、プラットフォームはWin32/Win64に対応してます。現状は動的リンクのみですが、いずれ静的リンクに可能なら対応しようと思ってます。動的リンクする場合は、各プラットフォーム毎のフォルダ(Win32、Win64)内の、onig.dllを実行時にこれらが見つけられるように、パスを通すか適切な位置に配置して下さい。自分で鬼雲をソースからビルドする場合。詳しいビルド方法は鬼雲のドキュメントを参照ということにしますが、エクスポートされた変数をDelphiから参照できるようにするために、一部ソースを修正する必要があります。詳しくはreadme.txtを・・

鬼雲というより元の鬼車が正規表現の文法を切り替えられるようになってるのですが、これにも対応しておきました。

文法を引数に取るコンスタクタを追加しておきました。指定しない場合は、デフォルトのrsPerlです。

ちなみに、当初はOSXにも対応しようとしてて、libonig.dylibをビルドしたのですが、これをダンプして中身を見ると、libonig.dylibが依存してる他のライブラリの相対パスなどではなく自分の環境依存の絶対パスが含まれていて、ちょっと、OSXの事がまだよくわかってなく、これを配布しても他の環境で動くのか不明なので、現状は自分でビルドして・・dashdash

 

2013年11月 9日 (土)

Delphiで正規表現(NSRegularExpression)

前回のDelphiで正規表現(VBScript) で書いたように、CocoaのNSRegularExpressionを使ってラップしたSystem.RegularExpressions.NSRegularExpressesion.pasを完成させましたdashdashdash

ということで、RegExPackの方を更新しておきました。詳しくはreadme.txtを。


Delphi XE4以降が必要です。

ところで、Cocoa APIを使って初めて本格的にプログラミングしたのですが、Cocoaで文字列を扱う場合は、NSStringクラスを使うことは知っていて、NSRegularExpressionクラスでもパターン、検索対象の文字列をNSStringクラスとしてやりとりするのですが、最後まで壮大な勘違いをしてましたdashdash

NSStringクラスというはUTF-16が基本sign02なんですね・・・・ずっと、UTF-8だと思ってましたsweat02sweat02。だから、NSStringのlengthプロパティはバイト(UTF-8のコードユニット)数ではなく、ワード(UTF-16のコードユニット)数を返す・・dashdashdash。ということで、Delphiのstring型と相性いいじゃんupupSystem.RegularExpressions.NSRegularExpressesion.pasの実装で、気付くまで、UTF16->UTF8へ変換したり、インデックスを調整するコードをごりごり書いていた・・・・

ということで、Delphi標準のMacapi.Foundation.pasに、Delphiのstring型をNSStringに変換するNSSTR関数がありますが、

思いっきりUTF-16<->UTF-8の変換のオーバーヘッドが発生してるようーーなsweat02sweat02。NSTR関数は使わないで、やるなら、NSStringクラスのstringWithCharacters:length:クラスメソッドと、getCharacters:range:インスタンスメソッドを使って、

ちなみに、stringWithCharacters:length:だと、指定した文字列がコピーされてメモリ上に重複してに持つことになるので、initWithCharactersNoCopy:length:freeWhenDone:インスタンスメソッドを使えば、Delphi側とメモリを共有できるっぽいup

このまま、調子に乗って、モチベーションが続く限り、次はUTF-16のPCRE版か、Oniguruma(Onigumo)版かな????

元々は、RFC 6265のクッキー仕様を実装しようとしてて、そこで正規表現使おうかなと思って、今は、クッキー仕様の実装ほったらかしで脱線しすぎ・・

2013年11月 4日 (月)

Delphiで正規表現(VBScript)

Delphiで正規表現とか今さら感がありますが・・

Delphiで正規表現というと、新しいものではDelphi XEでPCREを使った正規表現が使えるようになり、また、日本人でネットでDelphiのライブラリ等を公開してる人はほぼ全滅してて、その中でも公開している希望の星のSkRegEx があります(後、もちろん鬼車も) が、今まで自分は正規表現が必要な時は、だいたい、 ライセンスの問題に煩わされないVBScriptのRegExpオブジェクトを使ってきました。

で、今回、また、正規表現を使う必要があり、また、VBScriptのRegExpオブジェクトを使うつもりですが、せっかくなので、Delphi XEで導入された.NETライクな正規表現ライブラリ風に使えるように、脱線してRegularExpressions.pasをパクってみました。

System.RegularExpressions.VBScript.pasです。

ダウンロードはSkyDriveから。使用は各自の責任で・・



ちなみに、ラップしたVBScript.RegExpオブジェクトが貧弱なので、一部の機能はサポートしていません。詳しくは同梱のreadme.txtを・・また、ラップしたVBScript.RegExpはCOMオブジェクトなので、使用する前にCoInitialize(Ex)などで初期化してださい(メインスレッド以外で使う場合)。

Delphi XE以降が必要です。

後、更に脱線してOSX/iOS?向けにCocoaのNSRegularExpression をラップしたSystem.RegularExpressions.NSRegularExpressesion.pasも作成中なのですが、間に合わなかったので、次回・・・?dash

まぁ、特定のプラットフォーム向けのソフトウェアを作成する場合はこのように特定のプラットフォームに依存したエンジンを使ってもいいですが、クロスプラットフォーム向けのソフトウェアを作成する時に、プラットフォーム毎に正規表現エンジンを切り替えると、エンジン毎の正規表現の文法も違うことですし、おとなしく、エンジンがクロスプラットフォームなPCREを使っているDelphi標準のを使うか、Pure PascalなSkRegExを使った方が身のためですねdashdash

ここまでくると、次は、鬼車をラップして同じことをやりたくなってきたが、誰か代わりにつくってdashdash

ちなみに、Delphiの正規表現で使われてるPCREですが、去年のバージョン当たりから、UTF-16のエンコーディングに対応し始めて、これを使えば現状のUTF-8<->UTF-16の変換オーバーヘッドがなくなりますねup

« 2013年10月 | トップページ | 2013年12月 »

自作ソフトウェア

無料ブログはココログ

メモ