検索・置換 BUSCA

連立検索置換式を使って、資料をマークし、または変形します。マークと変形を同時にすることも可能です。検索式にはリテラル（文字列そのもの）、ワイルドカード、正規表現が選択できます。

上のテキストボックスに検索式を直接書き込むときは、[Ctrl]+[Enter]を押してください。特殊な文字を書き込むときは、Word文書からコピーするか、またはWord文書として保存した検索式をインポートします。「=>」の記号がない行は検索式と解釈し、それがある行は置換式と解釈します。エクスポートは複雑な検索置換式を保存するために使用します。

リテラル	文字（列）をそのまま検索・置換します。
ワイルドカード	ワイルドカードについては『基礎』を参照してください。ここではワイルドカードを拡張します。→「準備」
正規表現	正規表現についてはVBScriptの参考書を参照してください。ここでは正規表現を拡張します。→「準備」

ワイルドカードと正規表現の拡張

TEXTOSではWordのワイルドカードの機能を次のように拡張します。

&	単語文字1個以上。例：a&でab, axxxを検索します。&ですべての単語を検索します。
+	1個以上の連続（{1,}）
#	単語の境界(ワイルドカードの<. >；正規表現の\b)
\d	数字(1文字[0-9])
\D	数字以外(1文字[!0-9])
\s	空白文字（スペース、タブ、改行) と一致します。[ \t\n]
\S	空白文字以外（スペース、タブ、改行) と一致します。[! \t\n]
\w	単語に使用される文字(1文字[A-Za-z_0-9])
\W	単語に使用される文字以外(1文字[!A-Za-z_0-9])
\i	キリル文字
\I	キリル文字以外
\g	ギリシャ文字
\G	ギリシャ文字以外
\l	拡張ラテン文字
\L	拡張ラテン文字以外
\e	ハングル
\E	ハングル以外
\y	統合漢字
\Y	統合漢字以外
\h	ひらがな[ぁ-んー]
\H	ひらがな以外[^ぁ-んー]
\k	カタカナ[ァ-ンー]
\K	カタカナ以外[^ァ-ンー]
\z	漢字[\u4E00-\uFA6A々〆]
\Z	漢字以外[^\u4E00-\uFA6A々〆]
\j	日本語文字(1文字)[\u3041-\uFA6A々〆]
\J	日本語文字以外(1文字[^\u3041-\uFA6A々〆])

これらのうち、\d, \D, \s, \S, \w, \WはVBScriptの正規表現にあるものです。それ以外は拡張正規表現で用意します。拡張正規表現ではさら%で0個以上の拡張ラテン文字を示します。また、ワイルドカードでもタブと改行をそれぞれ正規表現の\t, \nを使用できます。

データ例

Private Sub UserForm_Activate() 'ユーザーフォーム表示

Set obj連想配列 = CreateObject("Scripting.Dictionary")

'連想配列オブジェクト生成

リテラルa[改行]e=>E

PrivatE Sub UsErForm_ActivatE() 'ユーザーフォーム表示

SEt obj連想配列 = CrEatEObjEct("Scripting.Dictionary")

'連想配列オブジェクト生成

拡張ワイルドカード\z

Private Sub UserForm_Activate() 'ユーザーフォーム表示

Set obj連想配列 = CreateObject("Scripting.Dictionary")

'連想配列オブジェクト生成

拡張正規表現\z+

Private Sub UserForm_Activate() 'ユーザーフォーム{{表示}}

Set obj{{連想配列}} = CreateObject("Scripting.Dictionary")

'{{連想配列}}オブジェクト{{生成}}

語頭と語末

América Rusia reconocer

というデータでワイルドカードを使って語頭がRまたはrの単語を検索するには、#[Rr]&とします。このように#はワイルドカードの「<」、または「>」に一致します。一方、正規表現の「#」(=\b)は英文字以外を単語境界としてしまうので、#r&で検索するとAmé{{rica}} {{Rusia}}{{reconocer}}のように、ricaも一致してしまいます。ここで、非単語文字\Lを使って\Lr&で検索すれば、América{{ Rusia}}{{ reconocer}}となって、検索された文字列の中に\Lに一致したブランクが含まれます。これを、

\Lr&

{{(\L)=>$1{{

という連立検索式を使って、América {{Rusia}} {{reconocer}}とします。

コントロール

オブジェクト名	キャプション/値
cmdインポート	インポート
cmdエクスポート	エクスポート
chk大小文字区別	大小文字区別
cmd実行	◎実行

コード

Option Explicit '変数を明示的に宣言

Dim 検索式配列$(), 検索式, 検索文字$, 置換文字$

Dim obj正規表現 As Object

Private Sub UserForm_Activate() 'ユーザーフォーム表示

Set obj正規表現 = CreateObject("VBScript.RegExp")

obj正規表現.Global = True '全体検索

End Sub

Private Sub cmd実行_Click()

If Len(Selection) = 0 Then MsgBox "範囲を選択してください。": Exit Sub

If optリテラル Then Call リテラル

If optワイルドカード Then Call ワイルドカード

If opt正規表現 Then Call 正規表現

End Sub

Private Sub cmdインポート_Click()

Dim FW&, SW& '最小化ボタン用変数

FW& = FindWindow("ThunderDFrame", S_検索置換フォーム.Caption)

'ハンドル

SW& = SetWindowPos(FW&, 1, 150, 150, 0, 0, &H1) 'フォームを後面に

With Dialogs(wdDialogFileOpen) 'ダイアログボックスを開く

.Name = "*.docx": .Display

If Left$(.Name, 1) = "*" Or .Name = "" Then Exit Sub

'ファイル名が入力されないときは終了

Documents.Open FileName:=.Name 'ファイルを開く

End With

txt検索式 = ActiveDocument.Range.Text 'ファイルの内容

ActiveDocument.Close 'ファイルを閉じる

SW& = SetWindowPos(FW&, -1, 150, 150, 0, 0, &H1) 'フォームを前面に

End Sub

検索式を外部のWordファイルからインポートするコマンドです。ファイルを開くダイアログボックスを使います。選択したファイルの内容をフォームの検索式のテキストボックスに代入します。

Private Sub cmdエクスポート_Click()

Dim FW&, SW& '最小化ボタン用変数

FW& = FindWindow("ThunderDFrame", S_検索置換フォーム.Caption) 'ハンドル

SW& = SetWindowPos(FW&, 1, 150, 150, 0, 0, &H1) 'フォームを後面に

Documents.Add: Selection = txt検索式 '新文書に検索式を代入

With Dialogs(wdDialogFileSaveAs) 'ダイアログボックスを開く

.Name = "*.docx": .Display

If Left$(.Name, 1) = "*" Or .Name = "" Then Exit Sub

'ファイル名が入力されないときは終了

ActiveDocument.SaveAs2 FileName:=.Name '名前をつけて保存

End With

ActiveWindow.Close

SW& = SetWindowPos(FW&, -1, 150, 150, 0, 0, &H1) 'フォームを前面に

End Sub

検索式を外部のWordファイルへエクスポートします。はじめに新文書に検索式をコピーし、これを保存するダイアログボックスを使います。

Private Sub UserForm_QueryClose(Cancel%, CloseMode%) '×終了ボタン

Set obj正規表現 = Nothing '正規表現オブジェクト解放

End '終了

End Sub

Private Sub リテラル()

検索式配列$ = Split(txt検索式, vbCrLf) '改行で分けた配列

For Each 検索式 In 検索式配列$

If 検索式 = "" Then Exit For

If InStr(検索式, "=>") = 0 Then '検索の場合…

検索文字$ = 検索式

置換文字$ = 検索式

Else '置換の場合…

検索文字$ = Left$(検索式, InStr(検索式, "=>") - 1)

置換文字$ = Mid$(検索式, InStr(検索式, "=>") + 2)

End If

With Selection.Find '選択範囲検索

.ClearFormatting '検索初期化

.Text = 検索文字$

.Replacement.ClearFormatting '置換初期化

.Replacement.Text = 置換文字$

.Replacement.Highlight = True '置換蛍光ペン

.MatchCase = chk大小文字区別

.MatchWildcards = False 'ワイルドカード：不使用

.Wrap = wdFindStop '末尾で検索終了

.Execute Replace:=wdReplaceAll '全置換

End With

Next

End Sub

テキストボックス内の検索式を改行でスプリットした配列にして、配列の要素であるそれぞれの検索式について置換します。「=>」がないときは検索文字に検索式を代入し、置換文字にワイルドカードの全体一致を示す「^&」を代入します。置換の場合は「=>」の左辺を検索文字、右辺を置換文字とします。選択範囲検索でワイルドカードを使用しないで、置換します。置換蛍光ペンを使用します。末尾で検索を終了させ、Word内で行われるような問い合わせをしません。

Private Sub ワイルドカード()

検索式配列$ = Split(txt検索式, vbCrLf) '改行で分けた配列

For Each 検索式 In 検索式配列$

If 検索式 = "" Then Exit For

If InStr(検索式, "=>") = 0 Then '検索の場合…置換式に変換

検索文字$ = 検索式

置換文字$ = "^&"

Else '置換の場合…

検索文字$ = Left$(検索式, InStr(検索式, "=>") - 1)

置換文字$ = Mid$(検索式, InStr(検索式, "=>") + 2)

置換文字$ = 正規表現置換$(置換文字$, "\$(\d)", "\$1", False)

'正規表現の後方参照($1)をワイルドカード(\1)に直す

End If

With Selection.Find '選択範囲検索

.ClearFormatting '検索初期化

.Text = 拡張ワイルドカード$(検索文字$)

.Replacement.ClearFormatting '置換初期化

.Replacement.Text = 置換文字$

.Replacement.Highlight = True '置換蛍光ペン

.MatchCase = True

.Format = True '書式を含む

.MatchWholeWord = False '単語の一部も検索

.MatchByte = False '全角半角文字を区別

.MatchSoundsLike = False '類似単語検索をしない

.MatchFuzzy = False '曖昧検索をしない

.MatchAllWordForms = False '活用形検索（～）

.MatchWildcards = True 'ワイルドカード：使用

.Wrap = wdFindStop '末尾で検索終了

.Execute Replace:=wdReplaceAll '全置換

End With

Next

End Sub

ほとんどリテラルと同じですが、ワイルドカードの部分一致は「\1」を使うので、正規表現のように「$1」を使用した時はこれに変換します。ワイルドカードは大小文字を区別し、また全角半角文字の区別、曖昧検索、活用形検索などはできません。

Private Sub 正規表現()

Dim 作業文字$

検索式配列$ = Split(txt検索式, vbCrLf) '改行で分けた配列

作業文字$ = Selection.Text '選択範囲

For Each 検索式 In 検索式配列$

If 検索式 = "" Then Exit For

If InStr(検索式, "=>") = 0 Then '検索の場合…

検索文字$ = "(" & 検索式 & ")"

置換文字$ = "{{$1}}"

Else '置換の場合…

検索文字$ = Left$(検索式, InStr(検索式, "=>") - 1)

置換文字$ = Mid$(検索式, InStr(検索式, "=>") + 2)

End If

検索文字$ = 拡張正規表現$(検索文字$)

置換文字$ = Replace(置換文字$, "\t", vbTab) 'タブコード

置換文字$ = Replace(置換文字$, "\n", vbCrLf) '改行コード

作業文字$ = 正規表現置換$(作業文字$, 検索文字$, 置換文字$, chk大小文字区別)

Next

Selection = 作業文字$ '選択位置に出力

Selection.ClearFormatting '書式クリア

End Sub

検索をするときは、検索式全体を(…)で囲んで、これに一致した部分$1を{{…}}で囲みます。検索文字を拡張正規表現に変換し、置換文字のタブコードと改行コードをWordのコードに変換します。先に選択範囲を作業文字に代入しておいて、これを検索式の数だけ置換し、最後に出力します。正規表現置換ではWordの装飾文字が使えないので、すべての書式をクリアします。

Private Function 拡張ワイルドカード$(ByVal W$)

W$ = Replace(W$, "\\", "!123") '\\をエスケープ

W$ = Replace(W$, "\$", "@@!!") '$をエスケープ

W$ = Replace(W$, "(^|$|\n)", "^13") '改行コードをワイルドカード式に

W$ = Replace(W$, "@@!!", "$") '$を復元

W$ = Replace(W$, "\t", "^9") 'タブコードをワイルドカード式に

W$ = Replace(W$, ".*", "*") '任意の文字0個以上（最大一致）

W$ = Replace(W$, "#", "<") '単語境界（語頭）

W$ = 正規表現置換$(W$, 拡張正規表現$("([\l|\]])<"), "$1>", False)

'単語境界（語末）

W$ = Replace(W$, "\.", "@@!!") '.をエスケープ

W$ = Replace(W$, ".", "?") '正規表現の任意の１文字をワイルドカード式に

W$ = Replace(W$, "@@!!", ".") '.を復元

W$ = Replace(W$, "\&", "@@!!") '&をエスケープ

W$ = Replace(W$, "&", "\l+") '単語文字1以上

W$ = Replace(W$, "@@!!", "&") '&を復元

W$ = Replace(W$, "\+", "@@!!") '+をエスケープ

W$ = Replace(W$, "+", "{1,}") '任意１文字をワイルドカード式に

W$ = Replace(W$, "@@!!", "+") '+を復元

W$ = Replace(W$, "\w", "[A-Za-z0-9_]") '英数字

W$ = Replace(W$, "\W", "[!A-Za-z0-9_]") '英数字以外

W$ = Replace(W$, "\d", "[0-9]") '数字

W$ = Replace(W$, "\D", "[!0-9]") '数字以外

W$ = Replace(W$, "\l", "[a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\xFF]")

'拡張ラテン文字

W$ = Replace(W$, "\L", "[!a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\xFF]")

'拡張ラテン文字以外

W$ = Replace(W$, "\i", "[\u0400-\u052F]") '拡張キリル文字

W$ = Replace(W$, "\I", "[!\u0400-\u052F]") '拡張キリル文字以外

W$ = Replace(W$, "\g", "[\u0370-\u03FF\u1F70-\u1F73]") 'ギリシャ文字

W$ = Replace(W$, "\G", "[!\u0370-\u03FF\u1F70-\u1F73]") 'ギリシャ文字以外

W$ = Replace(W$, "\y", "[\u3300-\u9FAF]") 'CJK互換漢字、統合漢字、漢字拡張文字

W$ = Replace(W$, "\Y", "[!\u3300-\u9FAF]") 'CJK互換漢字、統合漢字、漢字拡張文字以外

W$ = Replace(W$, "\e", "[\uAC00-\uD7AF]") 'ハングル

W$ = Replace(W$, "\E", "[!\uAC00-\uD7AF]") 'ハングル以外

W$ = Replace(W$, "\h", "[ぁ-ゞ]") 'ひらがな

W$ = Replace(W$, "\H", "[!ぁ-ゞ]") 'ひらがな以外

W$ = Replace(W$, "\k", "[ァ-ヴー]") 'カタカナ

W$ = Replace(W$, "\K", "[!ァ-ヴー]") 'カタカナ以外

W$ = Replace(W$, "\z", "[一-鶴]") '漢字

W$ = Replace(W$, "\Z", "[!一-鶴]") '漢字以外

W$ = Replace(W$, "\j", "[ぁ-ゞァ-ヾ一-鶴]") '日本語文字

W$ = Replace(W$, "\J", "[!ぁ-ゞァ-ヾ一-鶴]") '日本語文字以外

W$ = Replace(W$, "!123", "\\") '\\を復元

拡張ワイルドカード$ = W$ '返り値

End Function

Private Function 拡張正規表現$(ByVal W$)

W$ = Replace(W$, "\\", "!123") '\\をエスケープ

W$ = Replace(W$, "\&", "@@!!") '&をエスケープ

W$ = Replace(W$, "&", "\l+") '単語文字1以上

W$ = Replace(W$, "@@!!", "&") '&を復元

W$ = Replace(W$, "\%", "@@!!") '%をエスケープ

W$ = Replace(W$, "%", "\l*") '単語文字0個以上

W$ = Replace(W$, "@@!!", "%") '%を復元

W$ = Replace(W$, "\#", "@@!!") '#をエスケープ

W$ = Replace(W$, "#", "\b") '英単語の境界

W$ = Replace(W$, "@@!!", "#") '#を復元

W$ = Replace(W$, "\l", "[a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\xFF]") '拡張ラテン文字

W$ = Replace(W$, "\L", "[^a-zA-Z\xC0-\xD6\xD8-\xF6\xF8-\xFF]") '拡張ラテン文字以外

W$ = Replace(W$, "\i", "[\u0400-\u052F]") '拡張キリル文字

W$ = Replace(W$, "\I", "[^\u0400-\u052F]") '拡張キリル文字以外

W$ = Replace(W$, "\g", "[\u0370-\u03FF\u1F70-\u1F73]") 'ギリシャ文字

W$ = Replace(W$, "\G", "[^\u0370-\u03FF\u1F70-\u1F73]") 'ギリシャ文字以外

W$ = Replace(W$, "\y", "[\u3300-\u9FAF]") 'CJK互換漢字、統合漢字、漢字拡張文字

W$ = Replace(W$, "\Y", "[^\u3300-\u9FAF]") 'CJK互換漢字、統合漢字、漢字拡張文字

W$ = Replace(W$, "\e", "[\uAC00-\uD7AF]") 'ハングル音節文字

W$ = Replace(W$, "\E", "[^\uAC00-\uD7AF]") 'ハングル音節文字以外

W$ = Replace(W$, "\n", "\r") '改行コード(1)

W$ = Replace(W$, "\h", "[ぁ-ゞ]") 'ひらがな

W$ = Replace(W$, "\H", "[^ぁ-ゞ]") 'ひらがな以外

W$ = Replace(W$, "\k", "[ァ-ヴー]") 'カタカナ

W$ = Replace(W$, "\K", "[^ァ-ヴー]") 'カタカナ以外

W$ = Replace(W$, "\z", "[一-鶴]") '漢字

W$ = Replace(W$, "\Z", "[^一-鶴]") '漢字以外

W$ = Replace(W$, "\j", "[ァ-ヾぁ-ゞ一-鶴]") '日本語文字

W$ = Replace(W$, "\J", "[^ァ-ヾぁ-ゞ一-鶴]") '日本語文字以外

W$ = Replace(W$, "!123", "\\") '\\を復元

拡張正規表現$ = W$ '返り値

End Function

Private Function 正規表現置換$(ByVal A$, S$, T$, bolIC As Boolean)

obj正規表現.IgnoreCase = Not bolIC '大小文字区別を判定

obj正規表現.Pattern = S$ '検索パターン

正規表現置換$ = obj正規表現.Replace(A$, T$) '置換・代入

End Function

2012/5/21 H. Ueda