特定の文字列でgettextが正常に文字列を返No.07537
じぇえzの人 さん 15/03/14 08:57
 
バージョン:V8.51、32Bit、試用版

概要:
 特定の文字列において、gettext()を呼び出すと期待する文字列が返されない。


再現するコード:

 下記コードの目的は
  UTF-16の文字コードが書かれた、「&#xxxxx;」という文字列から「xxxxx」だけ
抜き出し
  文字コードから文字に置換する。「&#」で始まり、「;」で終わるという条件で
作成しています。

#flg = 0;
while ( #flg != 1 ) {
 $stline = gettext(0, 0, 1000, 0);
// message $stline;
 #posSt = strstr($stline , "&#");
 #posEn = strstr($stline , ";");
 if ( #posSt == -1) {
  #flg = 1;
 }

 // &# を除く ; までを抜き出す
 $beforeStr = gettext( #posSt+2, 0, #posEn, 0 );
// message str(#posSt) + "," + str(#posEn) + ", string=" + $beforeStr;
 $afterStr = unichar( val( $beforeStr ) );
 // 置換
 replaceall "&#" + $beforeStr + ";", $afterStr, word;
}


再現する文字列:
 @ '(。0﹏0。)っ { プヒ&#6543
9;ー
 A '⋆空蝉⋆'


出力が期待される結果:
 @ '(。0﹏0。)っ { プピー
 A '⋆空蝉⋆'


現象:
 上記コードで再現する文字列に対してマクロを実行し、処理中得られるx1とx2をも
とにgettext関数を呼び出すと
 戻り値の文字列が引数で渡したx1,x2より2つ前の位置の文字列を返す
 @3回目のループで発生
 A2回目のループで発生

その他:
 再現する文字列を小分けにした場合は発生しない
 過去バージョンでの確認は未実施


コードがおかしいのかなと思いましたが、gettextの挙動が途中で変になっているイ
メージです。
フォーラムのNo.33784において報告された不具合は修正されているようなので、別の
問題かと思い
ここに投稿させて頂きます。

[ ]
RE:07537 特定の文字列でgettextが正常にNo.07538
秀丸担当 さん 15/03/16 09:51
 

マクロとサンプルテキストで確かにそうなることが確認できました。

replaceallで、「, word」というパラメータがついているため、単語の一部とし
てみなされている場合にヒットしていないようです。
このサンプルの場合、隣接する文字に「0」があって、設定によってはこれによ
ってヒットしなくなっていました。
設定は、[その他]→[動作環境]→[検索]の「単語の検索で"abc"を検索する時、
"abc123"にはヒットさせない」がONになっていると、そう判断されていました。
「, word」を外すと大丈夫になると思います。

[ ]
RE:07538 特定の文字列でgettextが正常にNo.07539
じぇえzの人 さん 15/03/16 15:21
 
確認頂きありがとうございます。
回避策については理解しました。

gettextは置換のオプションによって動作が異なるという仕様
という認識で宜しいのでしょうか?

[ ]
RE:07539 特定の文字列でgettextが正常にNo.07540
秀丸担当 さん 15/03/16 16:09
 

このマクロにおいては、gettextに違いはなく、replaceallのほうに違いがあり
ました。
検索ダイアログで、「単語の検索」をONやOFFにして、「。」や
「フ」で検索すると違いがわかると思います。

オプションによる動作の違いを無くす目的の文としては、setcompatiblemode文
があります。
しかし「単語の検索で"abc"を検索する時、"abc123"にはヒットさせない」のオ
プションについてはsetcompatiblemode文では指定できませんでした。
必要性によっては検討すべきと思います。
ただ今回はたまたま隣接文字が「0」ですが隣接が「A」だったらこのオプション
のON/OFFに関わらず同じことが起きます。

今回の件についてはこのオプションは主な原因ではなく、「単語の検索」がON
相当になっていることに原因があるので、OFF相当(wordを外す)にするといい
と思います。

[ ]
RE:07540 特定の文字列でgettextが正常にNo.07541
じぇえzの人 さん 15/03/16 18:06
 
理解力が無く、何度もすみません。

>このマクロにおいては、gettextに違いはなく、replaceallのほうに違いがあり


数字の0が入っている@は分かり難いので、Aの方で説明させて頂きますが、


Aの文字列でマクロを実行させた場合

1回目のループで
gettext(1 +2, 0, 7, 0); が実行され、戻り値として"8902"が返ります

replaceallにより、文字列が置き換えられ、(環境依存文字なので@にしています)
'@空蝉@'

上記文字列に対しては
strstr($stline , "&#"); //戻り値が3
strstr($stline , ";"); //戻り値が10

ここまでは正しいと思うのですが、2回目のループでの
gettext( #posSt+2, 0, #posEn, 0 ); つまり
gettext( 3 +2, 0, 10, 0 ); の結果が
"31354"にはならず、"&#313"が返る理由が分かりません。

5文字目から10文字目を返す という動作にならないので頭を抱えています。

[ ]
RE:07541 特定の文字列でgettextが正常にNo.07542
h-tom さん 15/03/16 20:58
 

h-tom です。

>"31354"にはならず、"&#313"が返る理由が分かりません。
>
>5文字目から10文字目を返す という動作にならないので頭を抱えています。

マクロを実行する側の秀丸エディタは、プロポーショナルフォントを使ってます?

こちらの環境では、固定ピッチフォントの場合は正常ですが、プロポーショナル
フォントの場合はズレるようです。

環境依存文字は"@"にしてます。
-------------------------------------------
メイリオの場合
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'⋆空蝉⋆'
1,7, string=8902
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'@空蝉@'
3,10, string=&#313

-------------------------------------------
MS ゴシックの場合
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'⋆空蝉⋆'
1,7, string=8902
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'@空蝉@'
2,9, string=31354
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'@空蝉@'
4,11, string=34633
       ;0         1         2         3        
       ;0123456789012345678901234567890123456789
$stline;'@空蝉@"
-1,-1, string='

-------------------------------------------
ちなみに、数値文字参照を変換するなら、colderさんの変換モジュールが
ありますよ。

[ ]
RE:07542 特定の文字列でgettextが正常にNo.07543
じぇえzの人 さん 15/03/16 22:00
 
>>"31354"にはならず、"&#313"が返る理由が分かりません。
>>
>>5文字目から10文字目を返す という動作にならないので頭を抱えています。
>
>マクロを実行する側の秀丸エディタは、プロポーショナルフォントを使ってます?
>
>こちらの環境では、固定ピッチフォントの場合は正常ですが、プロポーショナル
>フォントの場合はズレるようです。

文字数じゃなく幅か何かでカウント・・・、フォントにそんな仕様なの?
と確認したところ、等幅では正常に期待する文字列が返されました。

カーソルx座標についてのヘルプを参照すると
文字数ではなくプロポーショナルフォントに限り特有のルールがあるみたいですね。
組み合わせ的にstrlenやstrstrとは相性が最悪のようで・・


頭を悩ませていた原因がはっきりして助かりました、ありがとうございます。


>ちなみに、数値文字参照を変換するなら、colderさんの変換モジュールが
>ありますよ。
何のどういった機能があるのかが検索結果だけでは分からず、
いちいち入れて確認するのが手間で他の方が作成されたマクロやモジュールには手は
出ませんでした。



[ ]
RE:07543 特定の文字列でgettextが正常にNo.07544
秀丸担当 さん 15/03/17 09:26
 

プロポーショナルフォントだとずれるということで、確かにstrstrとgettextの
組み合わせでずれていました。失礼しました。

x, y や gettext は固定ピッチフォントでは見た目上の座標を表すようにできて
いて、タブ文字があると4などで数えられたり、折り返しがあると x は文字列内
の位置とは関係ない数値になります。
そのため、プロポーショナルフォントだけでなく、固定ピッチフォントであって
も問題になる可能性がありました。

column, lineno や gettext2 を使うと文字列として扱いやすいと思います。

 $beforeStr = gettext( #posSt+2, 0, #posEn, 0 );

となっている部分の例では、gettext2にして、行番号は1から数えるので、

 $beforeStr = gettext2( #posSt+2, 0+1, #posEn, 0+1 );

とするといいと思います。

[ ]