plugins-oniguruma FrontPage | Edit | Raw | Index | 更新履歴 | RSS | kane4d

4D用正規表現のプラグイン(OnigRegexp?)

OnigRegexpとは

OnigRegexpは4Dに正規表現の機能を追加するプラグインです。 正規表現のエンジンに鬼車を使ってます。

用途

4Dで正規表現を使った少し複雑な文字列処理をしたい人向け

動作環境

ライセンス

非営利目的に限り自由に配布OK

サポート

無保証

ダウンロード

鬼車5.5.2をベースに再作成

Windows版だけです。 置換で(?<name>式)名前付き捕獲式集合に対応しました。\k<name>で取り出せます。

http://www.kanetaka.net/download/onigRegexp20070119.zip

4D2004.x対応のプラグイン形式

ベースになるonigurumaをv3.8.1にして、OSXとWindows両対応にしました。

http://www.kanetaka.net/download/OnigRegexp050530.zip

OnigRegexp?.bundle/Contents/Windowsの中身をWin4dxに入れれば、古い4Dでも使えます。

Windows専用

http://www.kanetaka.net/download/OnigRegexp040217.zip

コマンド

cnRegex(正規表現)に近くなるように書き直しました。

NextPos_l:=Onig_MatchText_l(対象文字列;正規表現;結果配列;Offset)

対象文字列Text->検索対象の文字列
正規表現Text->検索する正規表現
結果配列<-ArrayText?->検索結果が配列で返されます
OffsetLong->検索を始める位置
NextPos_l<-Longマッチした最後尾の位置

NextPos_l:=Onig_MatchBlob_l(対象Blob;正規表現;結果配列;Offset)

対象BlobBlob->検索対象の文字列
正規表現Text->検索する正規表現
結果配列<-ArrayText?->検索結果が配列で返されます
OffsetLong->検索を始める位置
NextPos_l<-Longマッチした最後尾の位置

Count_l:=Onig_SubstText_l(対象文字列;正規表現;置換文字列;置換回数)

対象文字列Text->置換対象の文字列
正規表現Text->検索する正規表現
置換文字列Text->\0〜\9と\n(\i手抜きしました)
置換回数Long->置換する回数(将来の予約)
Count_l<-Long変換回数

Count_l:=Onig_SubstBlob_l(対象Blob;正規表現;置換文字列;置換回数)

対象文字列Blob->置換対象の文字列
正規表現Text->検索する正規表現
置換文字列Text->\0〜\9と\n(\i手抜きしました)
置換回数Long->置換する回数(将来の予約)
Count_l<-Long変換回数

Count_l:=Onig_SplitText_l(対象文字列;正規表現;結果配列)

対象文字列Text->検索対象の文字列
正規表現Text->この正規表現で文字列を区切ります
結果配列<-ArrayText?->区切った結果が配列で返されます
Count_l<-Long区切った数

Count_l:=Onig_QuerySelection_l(フィールドポインタ;正規表現)

カレントセレクションに対し正規表現を使い絞り込み検索します。Onig_MatchText_lでループするより5〜10倍高速です。

フィールドポインタPointer->検索対象のフィールド(Text、String、Blob型)
正規表現Text->この正規表現で文字列を区切ります
Count_l<-Longセレクションのレコード数

内部で"$onigTemp0000"(0000はプロセスごとに違う数字)という名前のセットを使ってます。この名前とはダブらないせないように...

サンプルコード

Onig_MatchText_lを使った検索

全国郵便番号(約12万件)からの検索で470tickくらい

$tic_l:=Tickcount
ALL RECORDS([ZipCode?])
CREATE EMPTY SET([ZipCode?];"$ddd")
ARRAY TEXT($a;0)
While (Not(End selection([ZipCode?])))
`東西南北で始まる町の名前
$a:=Onig_MatchText_l ([ZipCode]kj_chomei;"^(東|西|南|北).*町$")
If ($a>0)
ADD TO SET([ZipCode];"$ddd")
End if 
NEXT RECORD([ZipCode])
End while 
USE SET("$ddd")
ALERT(String(Tickcount-$tic_l))

検索コマンド(Onig_QuerySelection_l)だとこんなにシンプル

全国郵便番号(約12万件)からの検索で90tickくらい

$tic_l:=Tickcount
ALL RECORDS([ZipCode?])
`東西南北で始まる町の名前
$err_l:=Onig_QuerySelection_l (->[ZipCode?]kj_chomei;"^(東|西|南|北).*町$")
ALERT(String(Tickcount-$tic_l))

漢字対応Substring関数

C_TEXT($0;$ret_t)
C_TEXT($1;$org_t)
C_LONGINT($2;$start_l)
C_LONGINT($3;$end_l)
C_LONGINT($err_l)
C_TEXT($pat_t)
ARRAY TEXT($mat_at;0)
$ret_t:=""
$org_t:=$1
If ($2=0)
$start_l:=1
else
$start_l:=$2
end if
If (Count parameters=3)
$end_l:=$3
End if 
Case of 
\ (Count parameters=2) & ($start_l>1)
$pat_t:="(?m).{"+String($start_l-1)+"}"+"(.+)"
$err_l:=Onig_MatchText_l ($org_t;$pat_t;$mat_at;0)
if ($err_l>0)
$ret_t:=$mat_at{2}
End if 

\ (Count parameters=2) & ($start_l=1)
$ret_t:=$org_t

\ (Count parameters=3) & ($start_l>1)& ($end_l>0)
$pat_t:="(?m).{"+String($start_l-1)+"}"+"(.{1,"+String($end_l)+"})"
$err_l:=Onig_MatchText_l ($org_t;$pat_t;$mat_at;0)
If ($err_l>0)
$ret_t:=$mat_at{2}
End if 

\ (Count parameters=3) & ($start_l=1) & ($end_l>0)
$pat_t:="(?m).{1,"+String($end_l)+"}"
$err_l:=Onig_MatchText_l ($org_t;$pat_t;$mat_at;0)
If ($err_l>0)
$ret_t:=$mat_at{1}
End if 

End case 

$0:=$ret_t

ひとこと

今年になって鬼車をアップグレードしようとしたら、コマンド名、定数名がすべて変更になってるじゃん。これを機にクラスを作りなおしました。

2chで正規表現検索のことが書いてあったんで機能追加してみました。

リンク