「
次/前の文字列を検索・改
」を編集中 (節単位)
ナビゲーションに移動
検索に移動
警告:
ログインしていません。編集を行うと、あなたの IP アドレスが公開されます。
ログイン
または
アカウントを作成
すれば、あなたの編集はその利用者名とともに表示されるほか、さまざまなメリットもあります。
スパム攻撃防止用のチェックです。 決して、ここには、値の入力は
しない
でください!
== 次/前の文字列を検索・改 2 == 2021-01-20 追加 === 改2の機能 === Mery 標準機能の「検索」「次/前の文字列を検索」コマンドとは完全に切りはなし、「検索/置換」ダイアログの '''オプション設定''' や '''検索履歴'''、'''検索文字列の強調表示''' の状態などを変更せずに検索・ジャンプできるようにしました。 Mery 標準機能の '''検索文字列の強調表示''' の状態(ハイライトされた文字列)を変更せずに検索・ジャンプしたい方は、こちらの「次/前の文字列を検索・改 2」マクロをお試しください。 <br> : ※ <span style="color:#c00;">マルチカーソルには非対応 </span>につき、マルチカーソル・複数選択範囲の状態から実行した場合は Mery 標準機能の「次/前の文字列を検索」コマンドを試行します (検索履歴やハイライト状態が変更されます)。 : ※ Javascript/JScript の機能で検索・ジャンプをおこなうため、<span style="color:#c00;">古い OS</span> や <span style="color:#c00;">低スペックの PC</span> 環境、かつ、<span style="color:#c00;">長大な文書(ドキュメント)</span>では動作がやや遅い場合があります。 「[[#次/前の文字列を検索・改|次/前の文字列を検索・改]]」マクロの [[設定項目]] のうち、4項目 var [[#設定項目: optionEnable|optionEnable]] = false; var [[#設定項目: historyEnable|historyEnable]] = false; var [[#設定項目: highlightEnable|highlightEnable]] = 0; var [[#設定項目: multiLinesEnable|multiLinesEnable]] = true; は固定状態での動作になります。<br> <br> 検索ダイアログのオプション項目「文末まで検索したら文頭に移動する」「大文字と小文字を区別する」「単語のみ検索する」にあたる <b><code>findAroundEnable</code> <code>matchCaseEnable</code> <code>onlyWordEnable</code></b> と検索文字列の出現回数のステータス表示設定 <b><code>hitCountEnable</code></b> の <syntaxhighlight lang="javascript" inline>true</syntaxhighlight>/<syntaxhighlight lang="javascript" inline>false</syntaxhighlight> 、長大な文書で動作が遅くなる場合の回避設定 <b><code>maxLength</code></b> の数値を任意にカスタマイズしてご利用ください。 === 改2のダウンロード === ダウンロード >> 「[[ファイル:次/前の文字列を検索・改_2.zip]]」 * マクロ「次の文字列を検索・改2.js」 * マクロ「前の文字列を検索・改2.js」 * 専用アイコン(マテリアルデザインっぽいアイコン) ; 変更履歴 * 改2 第1版 (2021-01-20) === 改2のソースコード === <syntaxhighlight lang="javascript" style="height:80em; overflow:auto;"> #title = "次の文字列を検索" #tooltip = "次の文字列を検索・改 2" // #icon = "select_next.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",124 // #title = "前の文字列を検索" // #tooltip = "前の文字列を検索・改 2" // #icon = "select_previous.ico" // #icon = "Mery用 マテリアルデザインっぽいアイコン.icl",125 // ▲ 「次/前」の部分を直してからマクロを登録すること ▲ // 「マテリアルデザインっぽいアイコン」のインデックスは、次 = 124 / 前 = 125 /** * ---------------------------------------------- * 「次/前の文字列を検索・改 2」 * sukemaru, 2021-01-20 * https://www.haijin-boys.com/wiki/次/前の文字列を検索・改#次/前の文字列を検索・改_2 * ---------------------------------------------- * 「次/前の文字列を検索」の機能をカスタマイズした検索ジャンプ。 * * ※ Mery 標準機能の「検索/置換」ダイアログ内のオプション設定を変更しない * (Mery の検索機能を利用せず Javascript で検索・ジャンプを実行する) * * ・検索履歴に残さない * ・実行前にあった検索ハイライトを維持する * (このマクロで検索した文字列をハイライト表示しない) * ・複数行選択からの検索ジャンプ可 * ・検索ヒット数をステータス表示可 * * ※ Mery Ver 3.0 以降のマルチカーソル・複数選択範囲から実行した場合は、 * Mery 標準機能の「次/前の文字列を検索」コマンドでのジャンプを試行する * (検索ダイアログのオプションを適用し、検索履歴に残る) */ var start = new Date(); // ---------- ▼ 「改2」版 設定項目 ▼ ---------- // ■ 検索する方向 ( 次: "Next" / 前: "Prev" ) var findNext = "Next"; // ■ 検索ダイアログの「文末まで検索したら文頭に移動する」オプションに相当 var findAroundEnable = true; // true なら、文末まで検索したら文頭に移動する // false なら、文末まで検索したらストップ // ※ 前を検索のときは、"文頭まで検索したら文末に移動する/しない" // ■ 検索ダイアログの「大文字と小文字を区別する」オプションに相当 var matchCaseEnable = false; // true なら、大文字と小文字を区別する // false なら、大文字と小文字を区別しない // ■ 検索ダイアログの「単語のみ検索する」オプションに相当 var onlyWordEnable = false; // true なら、選択範囲の文字列と一致する単語を検索する(半角英数字のみのとき) // false なら、選択範囲の文字列を部分的にふくむ単語も検索対象にする // ※ 検索文字列に半角英数字以外の文字が含まれている場合は、強制的に無効(false) // ■ 検索文字列の出現回数をステータスバーに表示 var hitCountEnable = true; // true なら、検索ヒット数をステータスバーに表示する // false なら、検索ヒット数をステータスバーに表示しない // ■ 長大な文書で実行して動作が遅くなる場合の回避設定 var maxLength = 0; // 0 ~ 99999 なら制限しない / 100000 以上の数値を設定すると文字数制限 // ※ 文字数が maxLength を超える文書では、強制的に // Mery 標準機能の「次/前の文字列を検索」コマンドで検索ジャンプする // ---------- ▼ 「改」旧版 設定項目 ▼ ---------- var optionEnable = false; // 「改2」版での初期値: false var historyEnable = false; // 「改2」版での初期値: false var highlightEnable = 0; // 「改2」版での初期値: 0 var multiLinesEnable = true; // 「改2」版での初期値: true // ---------- ▲ 設定項目 ▲ ---------- Status = ""; var d = editor.ActiveDocument, s = d.selection; var st = s.Text; var sy = ScrollY; var isSingleStream = ( ! s.Mode || s.Mode == 1 ); var isMultiLines = ( st.indexOf( "\n" ) > -1 ); var direction = /^(?:next|down|true|1)$/i.test( String( findNext ) ) ? 1 : 0; // meFindNext = 1 / meFindPrevious = 0 onlyWordEnable = /\W/.test( st ) ? false : onlyWordEnable; maxLength = ( maxLength >= 100000 ) ? maxLength : 0; historyEnable = ( maxLength && d.TextLength >= maxLength ) ? true : historyEnable; var keepOptions = ! historyEnable || multiLinesEnable && isMultiLines; // ---------- ▼ Main ▼ ---------- // Main: { // 「検索オプションを適用」して検索する場合 ※「次/前の文字列を検索」コマンド if ( optionEnable || ! isSingleStream ) { editor.ExecuteCommandByID( 2137 - direction ); // 次: 2136 / 前: 2137 highlightEnable = Boolean( highlightEnable ); } else if ( ! multiLinesEnable && isMultiLines ) { Status = "無効な検索文字列(複数行)。 "; break Main; } // 「次/前の文字列を検索・改 2」マクロ // 検索履歴に残さないで検索場合(検索オプションをリセットしない) else if ( keepOptions ) { if ( ! st ) { s.SelectWord(); st = s.Text; if ( ! st ) { Status = "検索文字列がありません。 "; break Main; } } var id, dt = d.Text; // 「次の文字列を検索・改 2」 if ( direction ) { var tp = Math.min( s.GetActivePos(), s.GetAnchorPos() ); id = SearchNext( st, onlyWordEnable, matchCaseEnable, dt, tp + 1 ); if ( id === -1 ) { Status = "文末まで検索しました。"; if ( findAroundEnable ) { id = SearchNext( st, onlyWordEnable, matchCaseEnable, dt ); } } } // 「前の文字列を検索・改 2」 else { var bp = Math.max( s.GetActivePos(), s.GetAnchorPos() ); id = SearchPrevious( st, onlyWordEnable, matchCaseEnable, dt, bp - 1 ); if ( id === -1 ) { Status = "文頭まで検索しました。"; if ( findAroundEnable ) { id = SearchPrevious( st, onlyWordEnable, matchCaseEnable, dt ); } } } if ( id > -1 ) { s.SetActivePos( id ); s.SetAnchorPos( id + st.length ); } } // 旧「次/前の文字列を検索・改」マクロ // 検索オプションをリセットして検索する場合(検索履歴に残す) else { var findAround = findAroundEnable ? meFindAround : 0; var matchCase = matchCaseEnable ? meFindReplaceCase : 0; var onlyWord = onlyWordEnable && ! /\W/.test( st ) ? meFindReplaceOnlyWord : 0; var flags = direction + findAround + matchCase + onlyWord; // 検索オプションをリセットして「次/前の文字列を検索」 s.Find( "", flags ); s.FindRepeat( direction + meFindRepeatWord ); if ( ! s.Text ) { Status = "検索文字列がありません。 "; break Main; } highlightEnable = Boolean( highlightEnable ); } // 検索強調表示の有無 if ( typeof highlightEnable === "boolean" ) { d.HighlightFind = highlightEnable; } // スクロール位置を調整 ScrollY = ( ScrollY === sy ) ? sy : s.GetActivePointY( mePosView ); } // ---------- ▲ Main ▲ ---------- // // 検索ヒット数をステータス表示 st = s.Text; var hitStatus = ( st && hitCountEnable ) ? ( onlyWordEnable ) ? WordHitStatus( st, dt || d.Text, matchCaseEnable ) : HitStatus( st, dt || d.Text, matchCaseEnable, countMinimum = false ) : " "; Status = hitStatus + ( Status ? " " + Status + " " : "" ) + TimerStatus( new Date, start ); // 選択範囲変更イベントを発生させる if ( st && isSingleStream && Status.indexOf( "すべての文章に" ) === -1 ) { var anc = s.GetAnchorPos(); var act = s.GetActivePos(); s.SetActivePos( anc ); s.SetActivePos( act, true ); } st = dt = null; // ---------- ▼ 関数 ▼ ---------- // /** * 関数 TimerStatus( end, start ) * start からの経過時間を [ s. sss 秒 ] で返す */ function TimerStatus( end, start ) { var elapsed = end - start; return " [ " + ( elapsed / 1000 ).toFixed( 3 ).replace( /\./, ". " ) + " sec. ]"; } /** * 関数 SearchNext( word, onlyWord, matchCase, txt [, offset] ) * 「次の文字列を検索」し、ヒットした位置を返す * * ※「単語のみ検索」「大文字と小文字を区別」のフラグを指定(必須) * ※ 検索開始位置のオフセット指定可 * ※ 戻り値は txt 全体におけるインデックス(pos >= 0) * または -1(ほかにヒットしなかったとき) * ※ 長大な文書ではオプションに関係なく遅い... */ function SearchNext( word, onlyWord, matchCase, txt, offset ) { offset = offset || 0; var pos; if ( onlyWord ) { var searchReg = RegExp( "\\b" + word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ) + "\\b" , matchCase ? "" : "i" ); pos = txt.slice( offset ).search( searchReg ); } else { word = matchCase ? word : word.toLowerCase(); txt = matchCase ? txt : txt.toLowerCase(); pos = txt.slice( offset ).indexOf( word ); } word = txt = null; return ( pos > -1 ) ? pos + offset : -1; // ヒットなしなら -1 } /** * 関数 SearchPrevious( word, onlyWord, matchCase, txt [, offset] ) * 「前の文字列を検索」し、ヒットした位置を返す * * ※「単語のみ検索」「大文字と小文字を区別」のフラグを指定(必須) * ※ 検索開始位置のオフセット指定可 * ※ 戻り値は txt 全体におけるインデックス(pos >= 0) * または -1(ほかにヒットしなかったとき) * ※ 長大な文書ではオプションに関係なく遅い... */ function SearchPrevious( word, onlyWord, matchCase, txt, offset ) { txt = offset ? txt.slice( 0, offset ) : txt; txt = matchCase ? txt : txt.toLowerCase(); word = matchCase ? word : word.toLowerCase(); var pos = txt.lastIndexOf( word ); if ( onlyWord && pos > -1 ) { var searchReg = RegExp( "\\b" + word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ) + "\\b" , "" ); // lastIndexOf() でヒットした word が「単語」かチェックする for ( var prev = Math.max( pos - 1, 0 ); prev > -1; prev -= 1 ) { pos = txt.slice( prev ).search( searchReg ); if ( pos > -1 ) { return prev + pos; } prev = txt.slice( 0, prev ).lastIndexOf( word ); } } word = txt = null; return pos; // ヒットなしなら -1 } /** * 関数 HitStatus( strSelection, strDocuText, matchCase, countMinimum ) * 選択文字列の出現回数を返す * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function HitStatus( word, txt, matchCase, countMinimum ) { word = matchCase ? word : word.toLowerCase(); txt = matchCase ? txt : txt.toLowerCase(); var s = editor.ActiveDocument.selection; var tp = Math.min( s.GetActivePos(), s.GetAnchorPos() ); var count = 0; var hit = 0; var offset = countMinimum ? word.length : 1; var pos = txt.indexOf( word ); while ( pos >= 0 ) { count ++; if ( pos === tp ) { hit = count; } pos = txt.indexOf( word, pos + offset ); } word = txt = null; return ( count > 0 ) ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } /** * 関数 WordHitStatus( strSelection, strDocuText, matchCase ) * 選択文字列の出現回数を返す(※単語のみ検索) * https://www.haijin-boys.com/wiki/検索ヒット数表示(選択文字列)#機能強化バージョン */ function WordHitStatus( word, txt, matchCase ) { word = word.replace( /[.*+?^=!:${}()|[\]\/\\]/g, "\\$&" ); var s = editor.ActiveDocument.selection; var bp = Math.max( s.GetActivePos(), s.GetAnchorPos() ); var reg = RegExp( "\\b" + word + "\\b", matchCase ? "g" : "gi" ); var count = ( $count = docu.match( reg ) ) ? $count.length : 0; var hit = ( txt.slice( 0, bp ).match( reg ) || [] ).length; word = txt = null; return ( count > 0 ) ? ( " ヒット数:" + count + " 件" + " ( " + hit + " 件目 ) " ).replace( /(\d)(?=(?:\d{3})+(?!\d))/g, "$1," ) : " "; } </syntaxhighlight>
編集内容の要約:
MeryWikiへの投稿はすべて、他の投稿者によって編集、変更、除去される場合があります。 自分が書いたものが他の人に容赦なく編集されるのを望まない場合は、ここに投稿しないでください。
また、投稿するのは、自分で書いたものか、パブリック ドメインまたはそれに類するフリーな資料からの複製であることを約束してください(詳細は
MeryWiki:著作権
を参照)。
著作権保護されている作品は、許諾なしに投稿しないでください!
このページを編集するには、下記の数式を計算してその答えを欄に入力してください (
ヘルプ
):
いちたすには =
キャンセル
編集ヘルプ
(新しいウィンドウで開きます)
スポンサーリンク
ナビゲーション メニュー
個人用ツール
ログインしていません
トーク
投稿記録
アカウント作成
ログイン
名前空間
ページ
議論
日本語
表示
閲覧
編集
履歴表示
その他
検索
スポンサーリンク
スポンサーリンク
案内
メインページ
ヘルプ
よくある質問
マクロリファレンス
マクロライブラリ
プラグインライブラリ
構文ファイル
テーマ
寄付・開発支援
練習用ページ
開発室
開発者のブログ
ツール
スポンサーリンク