last updated:2024/07/31

Hidemaru Q and A

第III部〜秀丸マクロのいろはにほへと
 マクロ内での「\」や特殊文字の使い方


マクロ内での「\」や特殊文字の使い方

【0】まえがき 〜 「\」や特殊文字を表記するために 〜

秀丸マクロで文字列を書きたいときには、" "(ダブルクォーテーションマーク:二重引用符)でくくってテキストファイル上に書きます。

ということは、その二重引用符の間に「二重引用符自体」とか「改行文字」とかを書きたいと思った場合に、どうすればよいでしょうか?
秀丸マクロの場合、これらはC言語と同様の書式を用いることで書き表すことができます。
具体的には、このような特殊文字は半角の「\」とその後ろに特定の文字を組み合わせることによって書き表す、という「きまり」になっています。

逆にいうと、「\」の文字を書きたいときに、単に「\」と書くとよろしくない、ということになります。

以下では、これらの特殊文字や、「\」自体を表記したい時の書き方を簡単にまとめてあります。

秀丸エディタ Ver.8.66以降では、C++11のRaw文字列リテラルや、C#の逐語的リテラル文字列 記法が使用出来るようになりました。この記法を使用すれば、「\」によるエスケープなしで、記述した文字列をそのまま、変数に入力できます。
(記法によっては制限があります。「Ver.8.66以降の場合」を参照)

秀丸エディタ Ver.9.19以降では、C# 11 Raw string のような記法も使えます。(「Ver.9.19以降の場合」を参照)

【1】「\」の意味

「\」を使う場合として、次のものが挙げられます。

エスケープシーケンスの例
\t タブ 16進数の「09」、10進数の「9」
\n 改行 16進数の「0A」、10進数の「10」
\" 「"」自身 16進数の「22」、10進数の「34」
\\ 「\」自身 16進数の「5C」、10進数の「92」
\xhh 任意の文字コード hh の文字 (16進数) 例えば「\x41」で、16進数の「41」、 10進数の「65」。これは文字でいうと「A」です。
\uhhhh 任意のユニコードで指定する文字
(16進数4桁固定)
\u79C0」で、「秀」という文字を示す。
16進数4桁までなので、コードポイントが 0x10000を超える場合は、サロゲートペアで表現する必要がある。
𠀋(U+2000B)は、
上位サロゲート \uD840
下位サロゲート \uDC0B
のように2文字文を使う表現になる。
\Uhhhhhhhh 任意のユニコードで指定する文字
(16進数8桁固定)
\U000079C0」で、「秀」という文字を示す。
𠀋(U+2000B)は、\U0002000B という表現になる。(Ver.8.52)

試しに、以下のマクロを実行してみてください。
@ と @ の間の表示に注目してみてください。

//---- 「\」の扱いを調べるテストマクロ ---------------------
$str[1] = "\t";
$str[2] = "\n";
$str[3] = "\"";
$str[4] = "\\";
$str[5] = "\x41";
$str[6] = "\u79C0";
$str[7] = "\uD840\uDC0B";
$str[8] = "\U0002000B";
#i = 1;
while( $str[#i] != "" ) {

    message "@" + $str[#i] + "@";
    #i = #i + 1;

}
endmacro;
//---- ここまで --------------------------------------------

【2】「\」の使用例

では、実際に「\」が出てくるマクロをいくつか書いてみましょう。

(a)ファイル「c:\test.txt」をオープンするマクロ

//---- ファイルをオープンするテストマクロ ------------------
openfile "c:\\test.txt";
endmacro;
//---- ここまで --------------------------------------------

ファイル名に「\」という文字を使いたい訳ですから、「\」自身の文字を表すために「\\」と表記します。

(b)改行を挿入するマクロ

//---- 改行を挿入するテストマクロ --------------------------
insert "改行する文章\n改行した後の文章";
endmacro;
//---- ここまで --------------------------------------------

改行を表現したい時は、「\n」でしたね。

(c)正規表現による改行検索を行うマクロ

実は、正規表現による検索・置換をする場合には、\の使い方が一見変わっているように見えます。【3】の例をごらんください。

【3】正規表現で使用する場合

//---- 改行検索を行うテストマクロ -------------------
searchdown "\\n", regular;
endmacro;
//---- ここまで -------------------------------------

この表記だと、二重引用符の中は、「改行文字」ではなく「\nという2文字の文字列」になっています。「\\」が、\という文字自身を表していますので、そうなりますね。
でも、正規表現による検索・置換をする場合には、これでよいのです。というか、このように表記しなければいけません。

なぜそうなるのかを説明するために、少し難しくなりますが秀丸エディタの内部動作を説明します。

秀丸エディタは正規表現による検索・置換をするために、HMJRE.DLLというプログラムを利用しています。秀丸エディタはHMJRE.DLLに、検索文字列を渡します。 HMJRE.DLLは渡された文字列を「解析」して、その中に「\nという2文字の文字列」が有った場合、それを「改行文字」だと「解釈」をします。
つまり、HMJRE.DLLに渡す文字列にも、マクロで表記するのと同様な「表記のきまり」があるということです。だから、改行文字を検索させたい場合は HMJRE.DLL に対して「\nという2文字の文字列」を送ってあげる必要があって、そのためには秀丸エディタのマクロ文では「\nという2文字の文字列」を記述してあげればよいことになっています。

というわけで、searchdown 文の引数として「\nという2文字の文字列」を記述してあげればよいので、 "\\\\n"という書き方になるのです。

上記のマクロを見て、「あれっ、改行って確か「\n」だから、「searchdown "\\n",regular;」じゃないの。試しに動かしたら、ちゃんと検索したぞー」とおっしゃる方もおられると思います。
これは、HMJRE.DLLが一応「改行文字そのもの」を送られてきた場合にも対応しているから動作しています。が、これは一般的な表記ではないので、複雑な文字列になると検索できない場合があります。というわけで、"\\\\n"と書くようにしましょう。

この表記法は、改行だけに限らず、\を使う表記すべてに当てはまります。ということで、たとえばタブ文字を検索したい場合は

searchdown "\\t", regular;

となりますし、\ という1文字を(正規表現中で)検索したいときには

searchdown "\\\\", regular;

となるわけですねヾ(^^;

#このように\を重ねて書かねばならないのはマクロ内だけです。正規表現による検索でもダイアログで普通に行う分には\は1個でよいです。

慣れてくると逆に混乱することがあるので、蛇足ですが(^^;)。

では、正規表現のマクロ記述は何でも\を重ねて書けばよいかというと、ダブルクォーテーションマーク(" )だけは異なります。

searchdown "\"", regular;

が正解です。ダブルクォーテーションマークは制御文字でなく普通の文字なので、\" でダブルクォーテーションマーク1文字をHMJRE.DLLに渡せるからです。あるいは、以下のようにして「\"という2文字の文字列」をHMJRE.DLLに渡しても動作します。

searchdown "\\\"", regular;

もし、マクロ内で正規表現がうまく動かない場合は、使用する正規表現を message文で表示してみてください。表示される内容が、HMJRE.DLLに渡される文字列となるので、実際にどのような文字列が渡されているのか確認出来ます。

【4】補足

Ver.8.54以降の場合

秀丸エディタ Ver.8.54以降では、 quote 関数が使えます。

この関数は、正規表現で使用されるメタ文字の前に"\"を追加し、エスケープします。 (正規表現で、その文字そのものとして扱われるようにする。秀丸エディタのヘルプ-正規表現の後半を参照)

現状では、以下の文字が対象になっています。

[ ] ( ) ^ $ . * + ? | \ { }

この文字列を、quote 関数で変換すると以下のように、各文字の前に"\"が追加された文字列を返します。

\[ \] \( \) \^ \$ \. \* \+ \? \| \\ \{ \}

秀丸エディタのパスを入力してみます。

C:\Program Files\Hidemaru\Hidemaru.exe

quote 関数の戻り値は以下になります。

C:\\Program Files\\Hidemaru\\Hidemaru\.exe

この戻り値を正規表現の検索で使用すれば、"C:\Program Files\Hidemaru\Hidemaru.exe" を、間違いなく検索可能になります。

Ver.8.66以降の場合

秀丸エディタ Ver.8.66以降では、C++11のRaw文字列リテラルや、C#の逐語的リテラル文字列 の記法が使用出来るようになりました。この記法を使えば、文字列を見やすく記述可能になります。

Raw文字列リテラル

秀丸マクロヘルプ - 式について - 文字列の「R"」から始まる文字列を参照

Raw文字列リテラルは、「R」から始め、以降「"」「Keyword」「(」と続き、ここまでが先頭を示す文字列になります。その後に文字列を記述し、「)」「Keyword」「"」の文字列で終端を示します。

Raw文字列リテラル
通常 "文字列"
Raw文字列リテラル R"Keyword(文字列)Keyword"
  • 「Keyword」は、前後に同じ文字列を使用する必要があります。
  • 「Keyword」は、0文字以上なので省略も可能です。省略する場合は、前後の「Keyword」を省略します。
  • 文字列中に括弧「( )」を使う場合には、「Keyword」を付けておくと、先頭と終端の括弧と区別できます。

簡単な記述例

message R"hidemaru("Raw文字列リテラル"の記述例です。)hidemaru";
//        "hidemaru"が「Keyword」になっている。

message R"("Raw文字列リテラル"の記述例です。)";
//      「Keyword」は省略可能

message R"hidemaru("Raw文字列リテラル(Raw String Literal)"の記述例です。)hidemaru";
//      文字列中に括弧を使用する場合は、「Keyword」を付けておくといいです。

message R"("Raw文字列
リテラル"の記述例です。)";
//      改行もそのまま改行と認識される。

message R"("Raw文字列
リテラル"の記述例です。
"\"マークやダブルクォートもそのまま表示されます。
"C:\Program Files\Hidemaru\Hidemaru.exe")";

message R"("Raw文字列
リテラル"の記述例です。
    インデントもそのまま文字列扱いされます。)";


逐語的リテラル文字列

秀丸マクロヘルプ - 式について - 文字列の「@"」から始まる文字列を参照

逐語的リテラル文字列は、「@"」から始まり、文字列を記述し、「"」で終わります。

逐語的リテラル文字列
通常 "文字列"
逐語的リテラル文字列 @"文字列"
  • 文字列中に「"」を記述する場合は「""」とする必要があります。

簡単な記述例

message @"""Raw文字列リテラル""の記述例です。";

message @"""Raw文字列
リテラル""の記述例です。";
//      改行もそのまま改行と認識される。

message @"""Raw文字列
リテラル""の記述例です。
""\""マークはそのまま表示されます。
""C:\Program Files\Hidemaru\Hidemaru.exe""";

message @"""Raw文字列
リテラル""の記述例です。
    インデントもそのまま文字列扱いされます。";



例として「message文」を使いましたが、文字列を指定する箇所なら何処でもこの記法が使えます。正規表現パターンを指定する場合にも使用できるので、見やすくなります。

また、ファイルパスを記述する際に、エクスプローラ等からコピーした文字列をそのまま使う事もできます。

openfile @"C:\Program Files\Hidemaru\HIDEMARU.TXT";

Ver.9.19以降の場合

秀丸エディタ Ver.9.19以降では、C# 11 Raw string のような記法も使えます。

「"""」から始め、「"""」で末尾と判断します。「"(ダブルクォート)」の連続数は3個以上あればよく、先頭と末尾の個数は同じにする事。

  • 一行で書く場合は、単純にで囲むだけです。

    message """先頭と末尾は3個なので、""(2個) まではそのまま記述可能""";
  • 複数行で書く場合は注意が必要です。

    • 「先頭」の直後に文字列は記述できません。すぐ改行する必要がありますが、「先頭」直後の改行は無視されます。
      「末尾」直前の改行とタブ・空白によるインデントは無視されます。「末尾」の直前は、改行またはタブ・空白によるインデントのみ許容されます。

      $header = "### start ###";
      $text   = """
      "先頭"と"末尾"は3個なので、""(2個) まではそのまま記述可能
      """;
      $footer = "### end ###";
      debuginfo 2;
      debuginfo $header + $text + $footer;
      endmacro;

      実行結果。
      「先頭」直後の改行と、「末尾」直前の改行とタブ空白によるインデントも無視されるので、全部つながって1行になっている。

      ### start ###"先頭"と"末尾"は3個なので、""(2個) まではそのまま記述可能### end ###

      「先頭」直後と「末尾」直前の改行が無視されるだけなので、空行を入れておけば改行可能。

      $header = "### start ###";
      $text   = """
      
      "先頭"と"末尾"は3個なので、""(2個) まではそのまま記述可能
      
      """;
      $footer = "### end ###";
      debuginfo 2;
      debuginfo $header + $text + $footer;
      endmacro;

      実行結果。
      空行は改行と認識され、3行で出力される。

      ### start ###
      "先頭"と"末尾"は3個なので、""(2個) まではそのまま記述可能
      ### end ###
    • インデント

      インデントも可能ですが、ベースライン(基準)は「末尾」の先頭になります。ベースライン(基準)より前のインデントは無視され、ベースライン(基準)より後のインデントは有効です。

      ベースライン(基準)より前には、タブ・空白によるインデントのみ許容されます。

      $header = "### start ###";
      $text   = """
      
                インデントなし
                  インデント有り
                下の行はインデントが「末尾」と同じなので空行扱いされる。
                
                """;
      $footer = "### end ###";
      debuginfo 2;
      debuginfo $header + $text + $footer;
      endmacro;

      実行結果。
      空行は改行と認識される。

      ### start ###
      インデントなし
        インデント有り
      下の行はインデントが「末尾」と同じなので空行扱いされる。
      ### end ###
    • NGになる例

      1. 先頭の「"""」の後に改行以外の文字がある場合

        $text   = """「先頭」
        と「末尾」は3個なので、""(2個) まではそのまま記述可能
        """;
      2. 末尾の「"""」の前にインデント(空白かタブ)以外の文字がある場合

        $text   = """
        「先頭」と「末尾」は3個なので、""(2個) まではそのまま記述可能
        です。""";
      3. 末尾の「"""」のインデント(空白かタブ)より前に文字がある場合

        $text   = """
        「先頭」と「末尾」は3個なので、""(2個) まではそのまま記述可能
            """;

ページトップ 目次に戻る