正規表現と連続置換No.00080
山紫水明 さん 03/11/07 21:32
 
  いであるさん,秀丸会議室 HIDESOFT2 #15695 からの続きです。

》 変換テーブルを用意しておくと連続置換が可能なツールは、フリーウェアで
》あるようですが、秀丸のタグ付き正規表現がとても便利なので、秀丸でおこな
》いたいと思っています。
 正規表現による連続置換と,複数ファイルの置換の2つが加わりますね。
 少し書きかえてみました。複数ファイルの方は少しややこしいので,とりあえ
ず正規表現置換ができるかどうか試してみてください。
 置換テーブルに正規表現で書き込みます。この場合は "\" は2つ重ねる必要
はないはずです。

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

//-------- ListConvert.mac -----------------------------------------//

//  変換リストによる連続置換     Ver1.02r                山紫水明
//  正規表現テスト版

//////// オプション ///////////////////
$folder = "D:\\Temp";
//$folder = "D:\\DATA\\変換リスト";
        //変換リストのあるフォルダーを指定する
        //フォルダの区切りは"\\" と "\"マークを2つ重ねる必要があります。

menu "&1 通常置換",
     "&2 正規表現による置換";
if(result == 0 ) endmacro;
else if( result == 1 ) #regular = 0;
else #regular = 1;

//  田楽DLLのロード
loaddll(hidemarudir + "\\DengakuDLL.dll");
if (!result) {
    message "田楽DLL をロードできませんでした。";
    endmacro;
}
$list = dllfuncstr("GETFILENAME", hidemaruhandle(0), "変換表の選択",
            $folder, "'変換リスト(*.*)'" );
if ( $list == "" ) {
    message "キャンセルされました。";
    freedll;
    endmacro;
} else {
    if ( strstr($list, "|") != -1 ) {
        message "一つの変換表しか選択できません。";
        freedll;
        endmacro;
    }
}
freedll;
#list = findhidemaru ($list);
if( #list >= 0 ) closehidemaru #list;

Menu:
menu "リストの変換方向",
     "&1 左 > > 右",
     "&2 左 < < 右";
#r = result;
if( #r == 0 ) endmacro;
if( #r == 1 ) goto Menu;
#tick = tickcount;
#handle1 = hidemaruhandle( 0 );
openfile "/h " + $list;
#handle2 = hidemaruhandle( 0 );
gofiletop;
while( code == 0x0d || code == '/' ) down;
#linecnt = linecount2 - lineno;//置換リスト数(行数)
#array = 30;    //配列個数(調整可能です)
#wordcnt = 0;   //変換語取得計算
#repcnt = 0;    //実際置換数計算
#totalcnt = 0;  //変換数計算
#totalrep = 0;  //総置換個数計算
#complete = 0;

while( #wordcnt <= #linecnt ) {
    call GetList;
    setactivehidemaru #handle1;
    title "**** 置換実行中です ****";
    disabledraw;
    if( #r == 2 ) call ConvertLtoR;
    else if( #r == 3 ) call ConvertRtoL;
    if( #complete ) break;
    setactivehidemaru #handle2;
}
closehidemaru #handle2;
enabledraw;
title 0;
$time = str( tickcount - #tick );
message "置 換 回 数\t" + str(#linecnt) +
      "\n有効置換回数\t" + str(#repcnt) +
      "\n置 換 総 数\t" + str(#totalrep) +
      "\n経 過 時 間\t" + leftstr($time, strlen($time) - 3) +
      "." + rightstr($time , 3) + " 秒" ;
endmacro;
//********************************************************************

GetList:
#i = 0;
while( #i <= #array ) {
    if(code == eof ) break;
    if( code == 0x0d ) {
        #linecnt = #linecnt - 1;
        down;
        continue;
    }
    beginsel;
    searchdown "[\t, , ]+", regular;
    if( !result ) {
        return;
        break;
    }
    $a[#i] = gettext( seltopx, seltopy, selendx, selendy );
    searchdown "[^\t, , ]", regular;
    escape;
    beginsel;
    golineend2;
    $b[#i] = gettext( seltopx, seltopy, selendx, selendy );
    movetolineno 1, lineno + 1;
    if( !result ) break;
    #i = #i + 1;
    #wordcnt = #wordcnt + 1;    //通算置換数
    if( #wordcnt > #linecnt ) break;
}
return;

ConvertLtoR:
#i = 0;
while( #i <= #array ) {
    if( #regular ) replaceallfast $a[#i], $b[#i], regular;
    else replaceallfast $a[#i], $b[#i];
    #totalrep = #totalrep + result;
    if( result ) #repcnt = #repcnt + 1;
    #i = #i + 1;
    #totalcnt = #totalcnt + 1;    //通算置換済数
    if( #totalcnt > #linecnt ) {
        #complete = 1;
        break;
    }
}
return;

ConvertRtoL:
#i = 0;
while( #i <= #array ) {
    if( #regular ) replaceallfast $b[#i], $a[#i],regular;
    else  replaceallfast $b[#i], $a[#i];
    #totalrep = #totalrep + result;
    if( result ) #repcnt = #repcnt + 1;
    #i = #i + 1;
    #totalcnt = #totalcnt + 1;    //通算置換済数
    if( #totalcnt > #linecnt ) {
        #complete = 1;
        break;
    }
}
return;
//-------------------------------------------------//



[ ]
RE:00080 正規表現と連続置換No.00081
いである さん 03/11/12 15:10
 
 山紫水明様、詳細なコメントありがとうございます。レスが遅くなり、お詫びしま
す。
 また、公開なさっているマクロを日頃使わせていただいていることも、この場を借
りてあわせ御礼申し上げます。

> 正規表現による連続置換と,複数ファイルの置換の2つが加わりますね。
> 少し書きかえてみました。複数ファイルの方は少しややこしいので,とりあえ
>ず正規表現置換ができるかどうか試してみてください。

 ご提供いただいたマクロを、試してみました。正規表現を含む21通りの置換を、一
気にすますことができました。とても嬉しい結果です。
 ここからさらに、複数ファイルをまとめて扱えるようになれば、私のほしい機能に
なるのですが、どうやら複雑なようですね。

 ともあれ、ご親切な対応ありがとうございました。自分でもマクロについて知識を
深める必要性を感じました。

[ ]
RE:00081 正規表現と連続置換No.00082
山紫水明 さん 03/11/12 20:19
 
 いであるさん,こんばんは。

》 ここからさらに、複数ファイルをまとめて扱えるようになれば、私のほしい
》機能になるのですが、どうやら複雑なようですね。

 別のところで発言されているように,linknext を用いれば簡単ですが,その
ためには対象ファイルを全部開く必要がありますね。
 開かないでフォルダ内の全置換をやるように作ってみました。
 なお,このバージョンではリストの書き方を少し変えて,通常置換と,正規表
現による置換が混在できるようにしてみました。そのために,区切りは半角のコ
ンマに限定しています。
  正規表現の場合は末尾に "r" か "regular"を付加してください。
      [例]
      あ,ア
      い,イ
      う,ウ
      [a-d],x,r
      え+,エ,regular

 何かお気づきのことありましたら,コメントください。
     では, (^^)/~
//------------------------------------------------------------------//

//  変換リストによる連続置換     Ver1.03β                山紫水明
//  正規表現&複数ファイルテスト版

//////// オプション ///////////////////
$folder = "D:\\Temp";
//$folder = "D:\\DATA\\変換リスト";
        //変換リストのあるフォルダーを指定する
        //フォルダの区切りは"\\" と "\"マークを2つ重ねる必要があります。

#tick = tickcount;

//  田楽DLLのロード
loaddll(hidemarudir + "\\DengakuDLL.dll");
if (!result) {
    message "田楽DLL をロードできませんでした。";
    endmacro;
}
if ($folder == "") {
    $folder = dllfuncstr("GETDIRNAME", hidemaruhandle(0),
                    "変換リストのあるフォルダを選択して下さい",
                    hidemarudir );
    if ($folder == "") {
        message "フォルダが選択されませんでした";
        freedll;
        endmacro;
    }
}
$list = dllfuncstr("GETFILENAME", hidemaruhandle(0), "変換リストの選択",
            $folder, "'変換リスト(*.*)'" );
if ( $list == "" ) {
    message "キャンセルされました。";
    freedll;
    endmacro;
} else {
    if ( strstr($list, "|") != -1 ) {
        message "一つの変換リストしか選択できません。";
        freedll;
        endmacro;
    }
}

menu "置換対象",
     "&C 現在のファイル",
     "&A フォルダ内全部";
if( result < 2 ) endmacro;
else if( result == 2 ) #object = 1;
else #object = 2;

#list = findhidemaru ($list);
if( #list >= 0 ) closehidemaru #list;
if( #object == 2 ) {
    call GetFilename;
    #fn = ##return;
} else #fn = 1;
freedll;
Menu:
menu "リストの変換方向",
     "&1 左 → 右",
     "&2 左 ← 右";
#direction = result;
if( #direction == 0 ) endmacro;
if( #direction == 1 ) goto Menu;

$cf = basename2;
#handle1 = hidemaruhandle( 0 );
#wordcnt = 0;   //変換語取得計算
#repcnt = 0;    //実際置換数計算
#totalcnt = 0;  //変換数計算
#totalrep = 0;  //総置換個数計算
#complete = 0;
call GetList;
call Replace;
if( #object == 2 ) {
    enabledraw;
    message "最初のファイルを置換しまた。異常ないか点検してください。"
    + "\n点検後に,中止は ESC キー,全ファイル置換はリターンキーを押す";
    inputpos "●●● 中止は ESC キー,継続はリターンキーを押す ●●●";
    if( iskeydown( 0x1b ) ) {
        question "置換を取り消しますか?";
        if( result == yes ) {
            disabledraw;
            while( #u <= #totalrep ) {
                undo;
                #u = #u + 1;
            }
        }
        endmacro;
    } else if( iskeydown( 0x0d ) ) {
        save;
        #i = 0;
        while( #i < #fn ) {
            if( $file[#i] != $cf ) {
                loadfile $file[#i];
                call Replace;
                save;
            }
            #i = #i + 1;
        }
    }
    loadfile $cf;
}
enabledraw;
title 0;
$time = str( tickcount - #tick );
message "置換ファイル数\t" + str(#fn) +
      "\n置 換 回 数\t" + str(#linecnt) +
      "\n有効置換回数\t" + str(#repcnt) +
      "\n置 換 総 数\t" + str(#totalrep) +
      "\n経 過 時 間\t" + leftstr($time, strlen($time) - 3) +
      "." + rightstr($time , 3) + " 秒" ;
endmacro;
/////////// Main End ///////////////////////////////////////////

Replace:
  title "**** 置換実行中です ****";
  disabledraw;
  if( #direction == 2 ) call ConvertLtoR;
  else if( #direction == 3 ) call ConvertRtoL;
return;
//********************************************************************

GetList:
openfile "/h " + $list;
#w = width;
config "w1000";//折り返しを一時的にひろげる
#handle2 = hidemaruhandle( 0 );
gofiletop;
while( code == 0x0d || code == '/' ) down;
#linecnt = linecount2 - lineno;//置換リスト数(行数)
##i = 0;
while( code != eof ) {
    if( code == 0x0d || gettext(0, y, 2, y) == "//") {
        #linecnt = #linecnt - 1;
        down;
        continue;
    }
    $$line = gettext( 0, y, linelen, y );
    ##len = strlen( $$line );
    ##a = strstr( $$line, "," );
    $a[##i] = leftstr( $$line, ##a );
    $$line = midstr( $$line, ##a + 1, ##len );
    ##len = strlen( $$line );
    ##a = strstr( $$line, "," );
    if( ##a < 0 ) {
        $b[##i] = $$line;
        $$c = "";
    } else {
        $b[##i] = leftstr( $$line, ##a );
        $$c = midstr( $$line, ##a + 1, ##len );
    }
    $regular[##i] = $$c;
    #y = lineno;
    movetolineno 1, lineno + 1;
    if( lineno == #y ) break;
    ##i = ##i + 1;
    #wordcnt = #wordcnt + 1;    //置換数
}
config "w" + str(#w);
setactivehidemaru #handle1;
closehidemaru #handle2;
return;

ConvertLtoR:
##i = 0;
while( ##i < #wordcnt ) {
    if( $regular[##i] == "r" || $regular[##i] == "regular" )
                            replaceallfast $a[##i], $b[##i], regular;
    else replaceallfast $a[##i], $b[##i];
    #totalrep = #totalrep + result;
    if( result ) #repcnt = #repcnt + 1;
    ##i = ##i + 1;
    #totalcnt = #totalcnt + 1;    //通算置換済数
}
return;

ConvertRtoL:
##i = 0;
while( ##i <= #wordcnt ) {
    if( $regular[##i] == "r" || $regular[##i] == "regular" )
                            replaceallfast $b[##i], $a[##i],regular;
    else  replaceallfast $b[##i], $a[##i];
    #totalrep = #totalrep + result;
    if( result ) #repcnt = #repcnt + 1;
    ##i = ##i + 1;
    #totalcnt = #totalcnt + 1;    //通算置換済数
}
return;

GetFilename:
##n = dllfunc("SETCURDIR", directory);
##fn = 0;
##n = dllfunc("ENUMFILE", "*.*");
while (1) {
    $file[##fn] = dllfuncstr("FINDNEXT");
    if ($file[##fn] == "") break;
    ##fn = ##fn + 1;
}
return ##fn;
//------------------------------------------------------------------------//



[ ]
RE:00082 正規表現と連続置換No.00083
いである さん 03/11/14 21:18
 
 山紫水明様、こんばんは。

> 別のところで発言されているように,linknext を用いれば簡単ですが,その
>ためには対象ファイルを全部開く必要がありますね。
> 開かないでフォルダ内の全置換をやるように作ってみました。

 こちらの勝手を聞いていただき、ありがとうございます。
 テストしてみましたが、私の正規表現のつめの甘さが露呈した(^^;)以外は何ら問
題なく、こちらの意図通りに全ての置換ができました。
 これまでちまちまと手間をかけていた作業が一瞬で終わり、感激しています。本当
に便利です。ご親切な対応、感謝します。

 ところで、あつかましくもお尋ねしますが、サブフォルダ以下のファイルは対象に
できないものでしょうか。
 開いたファイルを含むフォルダ内のファイルを全て対象にできるため、私自身の今
の用途ではこれで十分な機能なのですが、もしサブフォルダ以下も対象にできれば、
置換の最強マクロになると思いまして。
 現状でも十分満足していますが、ご検討いただければ幸いです。

[ ]
RE:00083 正規表現と連続置換No.00084
山紫水明 さん 03/11/15 10:29
 
 いであるさん,こんにちは。

》 ところで、あつかましくもお尋ねしますが、サブフォルダ以下のファイルは
》対象にできないものでしょうか。

 予想通り(^^; こういう要望が次にでてくるのではと思っていたところです。
多分可能ですので,バージョンアップするときにはやってみたいと思います。

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

[ ]
RE:00084 正規表現と連続置換No.00085
いである さん 03/11/18 13:20
 
 山紫水明様、たいへん嬉しいレスをありがとうございます。ずうずうしいことを言
ったのでドキドキしていたのですが、お願いしてよかった。バージョンアップを楽し
みにお待ちしています。

> 予想通り(^^; こういう要望が次にでてくるのではと思っていたところです。
>多分可能ですので,バージョンアップするときにはやってみたいと思います。


[ ]