検索ヒット数表示(選択文字列)

提供:MeryWiki
2019年7月20日 (土) 11:37時点におけるSukemaru (トーク | 投稿記録)による版 (「何件目」の表示を追加。関数バージョンを追加)
ナビゲーションに移動 検索に移動

ks 氏の「includeライブラリ」の StringEx.js(count 関数)と「検索ヒット数表示」マクロをもとに作成。

単独マクロバージョン

  • アクティブなタブの文書内から選択範囲の文字列に 完全一致 するものをカウントする。
  • ヒット件数はステータスバーに表示する。

選択範囲のある状態でマクロを手動で実行するか、「選択範囲が変更されたとき」のイベントマクロに設定して自動で実行させるのがよろしいかと。


※ このマクロと Mery 標準の検索メソッドとでは、ヒット数のカウントの仕方が異なります。

e.g.「あああああ」5文字だけの文書で「ああ」を検索した場合、このマクロでは "2件" とカウントしますが、Mery の検索メソッド(次/前を検索)では "4回" ヒットします。
→ 「何件目」かの表示は、うえの例のような範囲選択をしている場合には不正確な値を返します。


※ このマクロの実行にあたって include ライブラリは不要です。

※ このマクロでは、イベントマクロで利用する場合の処理速度を優先させるために「検索ヒット数表示(JScript)」 マクロのような正規表現検索には対応させていません。また、文字列のヒット判定では「大文字と小文字を区別する」が適用され、「単語のみを検索する」は適用されません。

※ イベントマクロで利用する場合は「遅延時間」を適宜調整しないと、大きな文書の編集のさいに動作がもたつくことがあります。

オプション指定をつけてヒット数を調べたい場合は、「ポップアップメニューで検索先にジャンプ 」マクロの include 版をご利用ください(イベントマクロにはできませんが)。

ソースコード

2019/07/20 更新

  • 全体のヒット件数のうしろに「何件目」のヒットかを追加
#title = "ヒット件数(選択文字列)"
#tooltip = "検索ヒット数表示(選択範囲の文字列)"
// #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",19

/**
 * アクティブなタブの文書内から選択範囲の文字列に完全一致するものをカウントする。
 * ヒット件数はステータスバーに表示する。
 * 
 * 選択範囲のある状態でマクロを手動で実行するか
 * イベント「選択範囲が変更されたとき」に設定して自動で実行させる。
 * 
 * ※ ks 氏の『includeライブラリ』より
 *     >> include/StringEx.js >> String.prototype.count() 
 *   のコードを拝借した。
 */

var timerStart = new Date();
Status = "";

var d = editor.ActiveDocument;
var s = d.selection;
var word = s.Text;

if ( word ) {
  var len = word.length;
  var dText = d.Text;

  // 大文字/小文字の区別なしにするなら、次の2行をアンコメントせよ
  // word = word.toLowerCase();
  // dText = dText.toLowerCase();

  var tPos = Math.min( s.GetActivePos(), s.GetAnchorPos() )
  var pos = 0,  count = 0,  hit = 0;
  while ( pos >= 0 ) {
    pos = dText.indexOf( word, pos );
    if ( pos >= 0 ) {
      count ++;
      if ( pos <= tPos  ) {
        hit = count;
      }
      pos += len;
    }
  }
  var SeparateNum = function( num ) {
    return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g, "$1," );
  }
  Status = " ヒット数:" + SeparateNum( count ) + " 件"
         + " ( " + SeparateNum( hit ) + " 件目 ) ";
  var TimerElapsed = function( end, start ) {
    var elapsedSec = ( ( end - start ) / 1000 ).toFixed( 3 );
    return "  [ " + elapsedSec.replace( /\./, ". " ) + " 秒 ]";
  }
  // 検索所要時間の表示が不要なら、次の1行をコメントアウトせよ
  Status += TimerElapsed( new Date(), timerStart );
}


組み込み用関数バージョン

2019/07/20 追加

  • 引数に指定した文字列の出現回数 "ヒット数:n 件 ( m 件目 ) " を返す。

※「バイト数」マクロなどへの追加コードとして利用できます。

※ 引数が「選択範囲の文字列」でない場合は、キャレット位置までのヒット数を「m 件目」として返します(ただし、キャレットのすぐ右に指定文字列がある場合は、『m 件目』の値 + 1 で返します)。

※ その他、仕様・注意事項については単独マクロバージョンに準じます。

使用例

// 例1. ステータスバーの表示内容に追加
if ( document.selection.Text ) {
  Status += "  " + HitStatus( document.selection.Text );
}

// 例2. 入力ダイアログで指定した文字列のヒット数
var word = Prompt( "検索文字列:", "" );
if ( word ) {
  Alert( "「 " + word + " 」 \n" + HitStatus( word ) );
}

組み込み関数コード

/* 
 * 関数 HitStatus( str )
 * 引数に指定した文字列の出現回数 "ヒット数:n 件 ( m 件目 ) " を返す
 * 引数 str: 選択範囲の文字列などの「文字列」オブジェクト
 * ※「大文字/小文字の区別なし」にしたい場合は、コメントアウトされた toLowerCase の行をアンコメントする
 */
function HitStatus( str ) {
  if ( str ) {
    // str = str.toLowerCase();
    var d = editor.ActiveDocument,  s = d.selection;
    var dText = d.Text;
    // dText = d.Text.toLowerCase();
    var tPos = Math.min( s.GetActivePos(), s.GetAnchorPos() );
    var len = str.length,  pos = 0,  count = 0,  hit = 0;
    while ( pos >= 0 ) {
      pos = dText.indexOf( str, pos );
      if ( pos >= 0 ) {
        count ++;
        if ( pos <= tPos  ) { hit = count; }
        pos += len;
      }
    }
    var SeparateNum = function( num ) {
      return num.toString().replace( /(\d)(?=(?:\d{3})+$)/g, "$1," );
    }
    return "ヒット数:" + SeparateNum( count ) + " 件"
           + " ( " + SeparateNum( hit ) + " 件目 ) ";
  }
}
スポンサーリンク