FindRegular のユニコード対応No.05231
山紫水明 さん 10/03/02 20:37
 
 秀まるおさん,お世話になっています。
  HmJre.dll の "FindRegular" 関数は現在ユニコードの文字列には対応してい
ないようですが,対応は難しいでしょうか。 

                  山紫水明

[ ]
RE:05231 FindRegular のユニコード対応No.05232
秀まるお さん 10/03/02 21:32
 
 FindRegular関数ですが、一応、ユニコードでもうまくいくと思います。

 秀丸のloadll/dllfuncで呼び出して使う分にはユニコード文字列も使えます。

    loaddll "hmjre.dll";
    #n = dllfunc("FindRegular", "\u00AE", "あい\u00AEうえお", 0);
    message str(#n);

 みたいなマクロはうまく動きます。

 もしかして他のアプリケーションソフトから呼び出して使うことを想定してい
る場合だとしたら、ユニコードには対応してないってことになりますけども。

 あるいは他にうまくいかない例があれば教えて欲しいです。

[ ]
RE:05232 FindRegular のユニコード対応No.05233
山紫水明 さん 10/03/02 22:10
 
 秀まるおさん,

> あるいは他にうまくいかない例があれば教えて欲しいです。

次のような文字列を書きます。
___ ___
AAA,AAA

実際はAのうえに - があるユニコード番号 \u100 の文字です。
この文字列の上で次のマクロを実行します。

$line = gettext2( 0, lineno, linelen2, lineno );
message $line;
loaddll "HmJre.dll";
#n = dllfunc( "FindRegular", "[,/]", $line, 0 );
message str(#n);
freedll;
endmacro;

こうすると #n には 12 が入ります。引数の 0 を他の数字に変えても同じ結果です。
何か使い方が間違っているのでしょうか。

                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05233 FindRegular のユニコード対応No.05235
Iranoan さん 10/03/02 22:37
 
 秀まるおさん、山紫水明さん今日は、Iranoan です。
 横から失礼します。
>  秀丸のloadll/dllfuncで呼び出して使う分にはユニコード文字列も使えます。
との事ですが、これって本当でしょうか?
 「本当でしょうか?」と書くと語弊がありそうですし、HmJre.dll というより、
dllfunc()/dllfuncstr() の話なのですが、Shift_JIS だけの時と同じつもり
でコーディングして OK なのでしょうか?
> 実際はAのうえに - があるユニコード番号 \u100 の文字です。
> この文字列の上で次のマクロを実行します。
<snip>
> #n = dllfunc( "FindRegular", "[,/]", $line, 0 );
の様な時は、秀丸エディタ Ver.8.00βの byteindex_to_charindex()/
charindex_to_byteindex() のヘルプを見ると、Unicode が含まれる場合はそ
れなりの処理をする必要がある気がします...。
 ##確かに、「ユニコード文字列も使えます」というのは正しいのでしょうが...。

 また HmJre.dll が、もし dllfuncw()/dllfuncstrw() 様の関数がなければ、
用意して頂けると助かります。     ~             ~

[ ]
RE:05235 FindRegular のユニコード対応No.05237
秀まるお さん 10/03/03 09:28
 
 秀丸担当に聞いてみたら、HmJre.dll関数の返り値については、Iranoanさんの
話にもある、

   byteindex_to_charindex

 って関数を使って変換してもらう仕様になってるらしいです。

 たぶん、以前にも同じような話があって、それでこの関数を秀丸側に追加した
のだと思います。

>  「本当でしょうか?」と書くと語弊がありそうですし、HmJre.dll というより、
> dllfunc()/dllfuncstr() の話なのですが、Shift_JIS だけの時と同じつもり
> でコーディングして OK なのでしょうか?

 実は知る人ぞ知るなんですけど、ユニコードの文字というのは秀丸エディタ内
部では4バイトの特殊な形で保持される仕組みになっていて、HmJre.dllの
FindRegular関数などでは、それらの内部コードがそのまま渡されています。な
ので、ユニコード文字1文字があたかも4文字あるかのように動作してまして、
それはそれでうまく機能している(ユニコード文字にもうまく対応している)と
いうことにはなります。

 秀丸エディタのstrlenやmidstr/leftstr/rightstrの関数などは、そういう内
部的な仕組みを隠蔽するように作られているんですけども、HmJre.dllはそうな
ってないので、先ほどのbyteindext_to_charindexとかの関数で変換してもらう
しか無いようです。

>  また HmJre.dll が、もし dllfuncw()/dllfuncstrw() 様の関数がなければ、
> 用意して頂けると助かります。     ~             ~

 その方がシンプルなので、対応させていただこくとにします。

 dllfuncwで呼び出す用の方は、FindRegularW って関数名になります。

[ ]
RE:05237 FindRegular のユニコード対応No.05238
秀まるお さん 10/03/03 09:46
 
 FindRegularW関数を追加したら解決するかと思ったんですが、その場合、
FindRegularW関数の返り値を

 wideindex_to_charindex

 って関数で変換してやらないとダメなので、手間としては現状と変わらないこ
とになってしまうようでした。

 ということでこれは没とさせていただきまして、代わりに、HmJre.dll側で
byteindex_to_charindex相当の変換を自動でする用のスイッチON/OFF関数を追加
しようと思います。

   SetUnicodeIndexAutoConvert

 って関数を追加して、それのパラメータに1を指定したら、後は自動変換する
って風にします。

[ ]
RE:05238 FindRegular のユニコード対応No.05242
山紫水明 さん 10/03/03 20:31
 
 秀まるおさん,

>   SetUnicodeIndexAutoConvert
> って関数を追加して、それのパラメータに1を指定したら、後は自動変換する
>って風にします。

 ユニコードのバイト数の扱い方については了解しました。解説ありがとうござ
いました。
 関数追加よろしくお願いします。

 もう一つ書いていた第3パラメータの数字を変えても結果が変わらないことに
ついてはどうでしょうか。
 先の例でいうと,0 を入れたら 12 でよいとして,4 を入れたら 8,8 を入れ
たら 4 になるはずだと思うのですが,いずれも 12 です。12 を入れても 12 で
す。13 以上にすると -1となり,正常になるようです。
 私の理解が間違っているのかもしれませんが,どう扱ったらいいでしょうか。

                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05235 FindRegular のユニコード対応No.05243
山紫水明 さん 10/03/03 20:33
 
 Iranoanさん,

>charindex_to_byteindex() のヘルプを見ると、Unicode が含まれる場合はそ
>れなりの処理をする必要がある気がします...。

 これは気づいていませんでした。いつものことですがどうもありがとうござ
います。
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05242 FindRegular のユニコード対応No.05244
Iranoan さん 10/03/03 20:50
 
 山紫水明さん今日は、Iranoan です。
>  もう一つ書いていた第3パラメータの数字を変えても結果が変わらないことに
> ついてはどうでしょうか。
 変わらなくて問題ないと思いますよ。
> 第3パラメータ(数値型): 検索を開始する桁位置を指定します。先頭か
>                            ら検索したい場合は0を指定します。
とあり、これはあくまで検索を開始する位置です。
> 返り値(数値型): ヒットした場合は桁位置(0以上の値)を返します。
>                    ヒットしなかった場合は-1を返します。正規表現の解
>                     釈その他でエラーが起きた場合は-2を返します。
とあり、検索開始位置からシフトとは書かれていません。
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~
 末尾のようなマクロで確認すれば解りやすいのでは?
//------------------------------------------------------------
$line = "000,000,000,000,000,";
loaddll "HmJre.dll";
message str( dllfunc( "FindRegular", "[,/]", $line, 0 ) );
message str( dllfunc( "FindRegular", "[,/]", $line, 4 ) );
message str( dllfunc( "FindRegular", "[,/]", $line, 8 ) );
message str( dllfunc( "FindRegular", "[,/]", $line, 12 ) );
freedll;
endmacro;

[ ]
RE:05244 FindRegular のユニコード対応No.05245
山紫水明 さん 10/03/03 21:38
 
 Iranoanさん,

>> 返り値(数値型): ヒットした場合は桁位置(0以上の値)を返します。
>>                    ヒットしなかった場合は-1を返します。正規表現の解
>>                     釈その他でエラーが起きた場合は-2を返します。
>とあり、検索開始位置からシフトとは書かれていません。

 あっ,そうか。桁位置というのは常に先頭から数えたものですね。てっきり検
索開始位置からの相対的桁数だと思っていました。
 ありがとうございました。
 「ヒットした場合は先頭からの桁位置(0以上の値)を返します。」とあれば,
          ~~~~~~~~~
私のような者でも誤解しなかったんですが・・・
 でも,そう誤解するのは私くらいなものか。

                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05245 FindRegular のユニコード対応No.05247
秀まるお さん 10/03/04 08:47
 
 ヘルプの方は、たしかにわかりにくいと思うので、修正させていただきます。

[ ]
RE:05247 FindRegular のユニコード対応No.05262
秀まるお さん 10/03/05 10:39
 
 っと今さらですみませんが、やはり、byteindex_to_charindexとかの変換を
HmJre.dll側でやるのはちょっと問題があるようなので、ボツということにさせ
ていただきます。

 すみませんが、マクロの方で変換の処理を書いて欲しいです。

 以前同じ話があった時に、元々そういう仕様でユーザー様に納得していただい
たはずが、僕がその話を知らずに勝手にHmJre側で処理した方がいいと思って返
事してしまったのが悪かったのです。実際HmJre.dll側にその処理を入れようと
すると、実はユニコード文字が半角文字なのか全角文字なのかという情報が秀丸
エディタ側でしか分からない情報ということになって、その情報を取得するのが
難しい(レベルダウンの可能性とか、あと、性能面での問題とかがある)という
のがありました。

[ ]
RE:05262 FindRegular のユニコード対応No.05263
秀まるお さん 10/03/05 10:43
 
 あと、HmJre.dllのヘルプの方には、byteindex_to_charindexの変換をする具
体的な例なんかも書かせていただきます。

[ ]
RE:05262 FindRegular のユニコード対応No.05264
秀まるお さん 10/03/05 10:53
 
 マクロの例です。

    loaddll "tkinfo.dll";
    #xTarget = 1;       //1桁目から検索の場合
    $target = "\u00C0\u00C1\u00C2";
    #x = dllfunc( "FindRegular", "\u00C1", $target
        , charindex_to_byteindex( $target, #xTarget ) );
    #len = dllfunc( "GetLastMatchLength");
    message "変換前: x= " + str(#x) + "  len=" + str(#len);
    #x = byteindex_to_charindex( $target, #x );
    #len = byteindex_to_charindex( midstr( $target, #x, 99999 ), #len );
    message "変換後: x= " + str(#x) + "  len=" + str(#len);
    endmacro;

 ややこしですけども…。

 全角/半角の区別があるのでどうしてもこういうややこしい処理になってしま
います。

[ ]
RE:05231 FindRegularのユニコード対応No.05287
h-tom さん 10/03/06 23:55
 

h-tom です。

>  HmJre.dll の "FindRegular" 関数は現在ユニコードの文字列には対応してい
>ないようですが,対応は難しいでしょうか。 

使用できる正規表現が、異なりますが、"hmonig.dll"に、Unicode版マクロ用関数
を追加しています。("FindRegularW"、 "FindRegularNoCaseSenseW")

よろしければ、使ってみてください。(試してくれる人募集中という段階ですが。)
 h-tom's Warehouse - 秀丸エディタ macro DLL
 http://homepage3.nifty.com/_htom/macro/macro_dll.html#label-18
dllfuncwで呼び出して、wcs〜の関数で、文字列操作すれば、問題ないハズ。

[ ]
RE:05287 FindRegularのユニコード対応No.05289
山紫水明 さん 10/03/07 16:34
 
 h-tomさん,コメントありがとうございます。

>使用できる正規表現が、異なりますが、"hmonig.dll"に、Unicode版マクロ用関
>数を追加しています。("FindRegularW"、 "FindRegularNoCaseSenseW")

 私のマクロ場合,gettext関数で取得した次のような複数種類の区切り符号で
区切られた文字列を分割するときに"[,/,]"という正規表現を使用しています。

@@@@,@@@@@,@@@@@,AAA
@@@/@@@@/@@@@@/BBBBBBBB
@@@@,@@@@,CCCCCC,@@@@@@
@@@@/@@@@/あああああ/うううううう
(@がユニコード文字です。)

//---------------------------------------
$seperator = "[,/,]";
$line = gettext2( 0, lineno, linelen2, lineno );
loaddll "HmJre.dll";
#a = dllfunc( "FindRegular", $seperator, $line, 0 );
#a = byteindex_to_charindex( $line, #a );
$part1 = leftstr($line, #a);
$line = wcsmidstr( midstr($line, #a), 1, 999 );
以下繰り返し。
//---------------------------------------

 HmJre.dll では, byteindex_to_charindex() が必要ですが, hmonig.dll の
FindRegular 関数ではこれを使わずにできますね。簡便です。

 ところで, FindRegularW 関数の方はどういう使い方をするのでしょうか。

     では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05264 FindRegular のユニコード対応No.05290
山紫水明 さん 10/03/07 16:48
 
 秀まるおさん,

> っと今さらですみませんが、やはり、byteindex_to_charindexとかの変換を
>HmJre.dll側でやるのはちょっと問題があるようなので、ボツということにさせ
>ていただきます。
> すみませんが、マクロの方で変換の処理を書いて欲しいです。

 了解しました。

> マクロの例です。
>    loaddll "tkinfo.dll";

1行目が変ですね。
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05289 FindRegularのユニコード対応No.05291
h-tom さん 10/03/07 17:32
 

h-tom です。

> 私のマクロ場合,gettext関数で取得した次のような複数種類の区切り符号で
>区切られた文字列を分割するときに"[,/,]"という正規表現を使用しています。

> HmJre.dll では, byteindex_to_charindex() が必要ですが, hmonig.dll の
>FindRegular 関数ではこれを使わずにできますね。簡便です。
>
> ところで, FindRegularW 関数の方はどういう使い方をするのでしょうか。

"HmJre.dll"の、"FindRegular"と同じです。(同じにしたはず。)
戻り値は、文字単位になるので、wcs系の関数を使う必要があります。
GetLastMatch〜の関数は、直前に実行した関数によって、戻り値がかわる
(バイト単位になったり、文字単位になる)ので、注意が必要です。

こんな感じかな?

#a = dllfuncw( "FindRegularW", $seperator, $line, 0 );
$part1 = wcsleftstr($line, #a);
$line = wcsmidstr( wcsmidstr($line, #a), 1, 999 );

うまく動かない場合は、再度連絡してください。

[ ]
RE:05291 FindRegularのユニコード対応No.05292
山紫水明 さん 10/03/07 21:59
 
 h-tomさん,

>こんな感じかな?

 これでうまくいくようです。

     では, (^^)/~
                                    山紫水明
                                    SANSHISUIMEI

[ ]
RE:05290 FindRegular のユニコード対応No.05294
秀まるお さん 10/03/08 09:09
 
 毎度間違いばかりですみません。

[ ]
RE:05290 FindRegular のユニコード対応No.05303
秀丸担当 さん 10/03/08 16:18
 

byteindex_to_charindex とは別の方法のHmJre側に
SetUnicodeIndexAutoConvert という関数を用意するという話ですが、いろいろ
話合った結果、やはりできそうということで次のβ版(とHmJreV3.13)のほうで
対応させていただきます。

[ ]
RE:05303 FindRegular のユニコード対応No.05305
山紫水明 さん 10/03/08 19:53
 
 秀丸担当さん,

>SetUnicodeIndexAutoConvert という関数を用意するという話ですが、いろいろ
>話合った結果、やはりできそうということで次のβ版(とHmJreV3.13)のほう
>で対応させていただきます。

 それはよかった。期待しています。

                                    山紫水明
                                    SANSHISUIMEI

[ ]