ユニークな unicode記号 を含む HTML の正No.07074
rosegardenyk さん 12/06/27 19:33
 
rosegardenykです。いつもお世話になっています。またマクロ初心者の質問です。

—とか○にcの© 以下を表す半角の &le といったShift_JISにはないユ
ニークな unicode記号 を含む HTML の正規表現置換処理時に生じる桁ずれ関する質
問です。秀丸マクロからloaddllしてdllfuncで呼び出した dllfunc("FindRegular"...
に関しては、HmJre Help に説明があります。しかし dllfuncstr("ReplaceRegular"
の場合も、Webから取得した HTML にユニークな unicode記号 が含まれていると下記
マクロのように、桁ずれを起こして、Helpに書いてある対策(下記マクロのおまじな
い1 #n = dllfunc ("SetUnicodeIndexAutoConvert)も効果がなく、意図した置
換処理が行われません。 

へぼプログラマーなりに、私も2つ(下記マクロのおまじない2と3)ほど解消策を
ひねり出しましたが、おまじない2はいかにも素人っぽくて気に入りません。しかし、
何故これで解消されるのか理由がわかればより玄人っぽい対処法を工夫できるかもし
れません。どなたかうまくいくそのわけを教えていただけますでしょうか? おまじ
ない3 は主だったユニークな unicode記号は個別に事前に置換するのは問題ありませ
んが、その他のshift_JISにないマイナーな記号はまとめて"?"に置換してしまうとい
った方法がわかりません。
今回のユニークな unicode記号 が含まれているテキストの問題はsaveする前段階の
課題なので、何でエンコードするかは関係ないと思っています。共通的な課題なので
すでに解決策をお持ちの方が多いのではないかと思っています。より良い桁ずれ対策
をご教示くださると助かります。 


//TEST 用マクロ 「はい」を選ぶとそれぞれの対策(おまじない0〜3)の結果が新
規ファイルに表示されます。
 loaddll "hmjre.d ll";
 $uri = "http://www.nejm.org/doi/full/10.1056/NEJMsa1200223";
 call HttpGetBinary $uri ;
 $text = $$return;
 #pos = dllfunc("FindRegular", "Special Article</p><h1>[^~]*?Read the Full A
rticle\\.\\.", $text, 0);
//抄録部分のみ抽出
 $text = leftstr($text, #pos + dllfunc("GetLastMatchLength"));
 $text = midstr($text, #pos);
question "「はい」:おまじない0(対策なし)。桁ずれあり。取得したテキスト
(文字変数)に対しすぐにタグ除去他の処理をするとテキストに2カ所ある &mdash
 記号 (Sift-JISにない)の影響で桁ずれをおこす。\n 「いいえ」 パス"; if
(result) {
  $text2 = dllfuncstr("ReplaceRegular","<.+?>", $text, 0, "", 2);
  $text2 = dllfuncstr("ReplaceRegular","Full Text of .+?\\.\\.\\.", $text2,
0, "\n", 2);
  $text2 = dllfuncstr("ReplaceRegular","(.+)", $text2, 0, "∬\\1", 2);
  newfile;
  selectall;
  insert "おまじない0 (対策なし)。桁ずれあり。取得したテキスト(文字変数)に
対しすぐにタグ除去他の処理をするとテキストに2カ所ある &mdash 記号 (Sift-
JISにない)の影響で桁ずれをおこす。\n" + $text2;
 }
question "「はい」:おまじない1。桁ずれあり。桁ずれ防止策の一つ #n = dllfu
nc(\"SetUnicodeIndexAutoConvert\の効果なし。 「いいえ」:パス";
 if (result) {//おまじない1
  loaddll "hmjre.dll";
  #n = dllfunc("SetUnicodeIndexAutoConvert", 1);//unicode文字によるずれを解消
  $text2 = dllfuncstr("ReplaceRegular","<.+?>", $text, 0, "", 2);
  $text2 = dllfuncstr("ReplaceRegular","Full Text of .+?\\.\\.\\.", $text2,
0, "\n", 2);
  $text2 = dllfuncstr("ReplaceRegular","(.+)", $text2, 0, "∬\\1", 2);
  newfile;
  selectall;
  insert "おまじない1。桁ずれあり。桁ずれ防止策の一つ #n = dllfunc(\"SetUn
icodeIndexAutoConvert\の効果なし\n"  + $text2;
 }
question "「はい」:おまじない2。桁ずれなし。一回ファイルに落としてから同一
内容を文字変数に拾い直すことで解消可。 「いいえ」:パス";
 if (result) {//おまじない2
  newfile;
  insert $text;
  selectall;
  $text2 = gettext(seltopx, seltopy, selendx, selendy, 0);
  loaddll "hmjre.dll";
  $text2 = dllfuncstr("ReplaceRegular","<.+?>", $text2, 0, "", 2);
  $text2 = dllfuncstr("ReplaceRegular","Full Text of .+?\\.\\.\\.", $text2,
0, "\n", 2);
  $text2 = dllfuncstr("ReplaceRegular","(.+)", $text2, 0, "∬\\1", 2);
  selectall;
  insert "おまじない2。 桁ずれなし。一回ファイルに落としてから同一内容を文
字変数に拾い直すことで解消可\n"  + $text2;
 }
question "「はい」:おまじない3。桁ずれなし。 Shift_JISにない unicode(&md
ash等)をshift-JISにある記号に置換してから、タグ除去他の処理をすることで解消
可  「いいえ」 パス";
 if (result) {//おまじない3
  loaddll "hmjre.dll";
  $text2 = dllfuncstr("ReplaceRegular", "\u2014", $text, 0, "−", 2);
  $text2 = dllfuncstr("ReplaceRegular","<.+?>", $text2, 0, "", 2);
  $text2 = dllfuncstr("ReplaceRegular","Full Text of .+?\\.\\.\\.", $text2,
0, "\n", 2);
  $text2 = dllfuncstr("ReplaceRegular","(.+)", $text2, 0, "∬\\1", 2);
  newfile;
  selectall;
  insert "おまじない3。桁ずれなし。 Shift_JISにない unicode(&mdash等)をs
hift-JISにある記号に置換してから、タグ除去他の処理をすることで解消可\n"  + $
text2;
 }

 endmacro;
// **** $$1 : Uri **********************************************************
***************************
HttpGetBinary:
 ##objHttp = createobject("Msxml2.XMLHTTP");
 callmethod ##objHttp, "Open", "GET", $$1, 0;
 callmethod ##objHttp, "Send";
 $$html = getpropstr(##objHttp, "ResponseText");
 loaddll "hmjre.dll";
 ##n = dllfunc("SetUnicodeIndexAutoConvert", 1);//unicode文字によるずれを解消
 ##pos = dllfunc("FindRegularNoCaseSense", "(?<=charset=).+?(?=\")", $$html,
 0);
 $$charset = midstr($$html, ##pos, dllfunc("GetLastMatchLength"));
 if (!getresultex(10)) message "Http内容の取得に失敗しました。";
 else {
  if ($$charset == "utf-8") {
   $$response = getpropstr(##objHttp, "ResponseText");
    releaseobject ##objHttp;
   return $$response;
  }
 }
 ##objStream = createobject( "ADODB.Stream" );
 callmethod ##objStream, "Open";
 setpropnum ##objStream, "Type", 1;//adTypeBinary

 allowobjparam 2;
 callmethod ##objStream, "Write", getpropstr( ##objHttp, "responseBody" );
 allowobjparam 0;
 
 setpropnum ##objStream, "Position", 0; //Posionを先頭にセット
 setpropnum ##objStream, "Type", 2;//adTypeText  //データ型をテキストに設定
 setpropstr ##objStream, "charset", $$charset; //Streamの内容を変換する文字
セット
 $$output_text = callmethod_returnstr(##objStream, "ReadText"); // -1:adRead
All (Stream内容をテキストとして読み込む)
 callmethod ##objStream, "Close";
 releaseobject ##objStream;
 releaseobject ##objHttp;
return $$output_text;

[ ]
RE:07074 ユニークな unicode記号 を含む No.07075
秀まるお2 さん 12/06/27 22:50
 
 毎度お手数かけてすみません。

 再現テストしたら、たしかにおかしいようでした。

 それで、HmJre.dllのソースコードを見直した所、ReplaceRegulraの内部での、
SetUnicodeIndexAutoConvertでの変換の処理が明らかに間違ってることが分かっ
てしまいました。変換の処理が内部的に多重に処理されてしまってる所がありま
した。

 連続して置換する指定をするとダメでした。

 とりあえず現段階ではバグってるのでどうにもうまく動かないってことになっ
てしまうようです。大変失礼しました。

 明日中に直してまたβ版としてアップロードさせていただきます。それまです
みませんが少々お待ちください。

 (変数用のメモリサイズを指定するオプションも追加しましたので)

[ ]
RE:07075 ユニークな unicode記号 を含む No.07076
秀まるお2 さん 12/06/27 23:24
 
 とりあえずの回避策としては、

 call HttpGetBinary $uri ;
 $text = $$return;

 の直後に

 ##n = dllfunc("SetUnicodeIndexAutoConvert", 0);

 を入れて、ユニコード文字の桁位置変換をなしにしてしまう手がありました。

 この後のReplaceRegularの処理ではユニコード文字の桁位置配慮は必要無いの
で、これでも一応マクロはうまく動くようではあります。

 どっちにしてもHmJre.dllは修正させていただきます。

[ ]
RE:07076 ユニークな unicode記号 を含む No.07079
rosegardenyk さん 12/06/28 14:50
 
秀まるお2殿
> どっちにしてもHmJre.dllは修正させていただきます。
V8.20β25をDLしてテストしたところ、おまじない1(#n = dllfunc("SetUnicodeInd
exAutoConvert", 1);//unicode文字によるずれを解消)でも効果が発揮されて、dllf
uncstr("ReplaceRegular"…,2)の連続処理に成功しました。agileな対応ありがとう
ございました。感謝します。

[ ]