1.5. 検索・置換
1.5.3. ワード検索・置換
Word文書の中の要素を検索してマークする実験をします。検索の方法は「リテラル」「ワイルド カード」「正規表現」の3種類です。
(a) リテラル検索
「リテラル」では、文書中の文字(列)をそのまま指定して検索文字列強調します。
後で見るワイルドカードや正規表現で使う特殊な文字(メタキャラクタ)もエスケー プせずにそのまま使えます。たとえば、「?」や「*」などです。検索式をテキストボ ックスに書き、「実行」ボタンを押します。検索式は後で確認できるように Word な どの文書に一度書いておき、それをCopy & Pasteするとよいでしょう。とくに英語以 外の各国語の文字は直接検索式のテキストボックスに書き込めないので、そのように する必要があります。
検索式を連立することもできます。そのときは改行のために[Ctrl]+[Enter]を押して ください。または、Word文書の中で改行したものを貼り付けます。
検索の結果、該当部分が蛍光ペンで示されます。
入力文:
Me voy de aquí dejando parte de mi corazón entre todos mis amigos españoles.
結果:リテラル検索:mi
Me voy de aquí dejando parte de mi corazón entre todos mis amigos españoles.
結果2:リテラル検索:β
βιβλος γενεσεως ιησου χριστου υιου δαβιδ υιου αβρααμ
αβρααμ εγεννησεν τον ισαακ ισαακ δε εγεννησεν τον ιακωβ ιακωβ δε εγεννησεν τον ιουδαν και τους αδελφους αυτου
「大小文字区別」をチェックするとたとえば「m」は小文字のmだけを検索します。
(b) リテラル置換
1 In thE bEginning God crEatEd thE hEavEns and thE Earth.
2 ThE Earth was without form, and void; and darknEss was on thE facE of thE dEEp.
And thE Spirit of God was hovEring ovEr thE facE of thE watErs.
69 結果2:リテラル:e=>E
1 In thE bEginning God crEatEd thE hEavEns and thE Earth.
2 ThE Earth was without form, and void; and darknEss was on thE facE of thE dEEp.
And thE Spirit of God was hovEring ovEr thE facE of thE watErs.
(c) TEXTOSのワイルドカードと正規表現の違い
次は正規表現だけで使用が可能です。
* 直前の文字や式と 0 回以上一致します。
? 直前の文字や式と 0回または 1 回一致ます。
(*|*|...) 複数の句をグループ化します。ネストすることができます。
*これらは検索式、置換式の連立式を用いることによって可能になります。一方、ワ イルドカードには次の利点があります。
(1) Wordの文書の書式を保ったまま検索と置換の処理ができます。
(2) 語の境界(#, <, >)はラテン拡張文字でも可能です。
たとえば、母音(特殊文字を含む)で始まる語を検索してみましょう。
結果:ワイルドカード:#¥v%
Es gibt das radikal Böse, aber
ワイルドカードでは特殊文字と一般の母音の間を単語境界と見なさないので問題なく 検索できますが、正規表現では特殊文字と一般の母音の間を単語境界と見なしてしま うので、後方参照を使います。たとえば、子音で終わる単語を検索するにはワイルドカ ードを次のように指定します。ここではアポストロフィ( ' )を含めます。
結果:ワイルドカード:[’a-z]@¥c#
Cosa c’era ne’l fior che m’ai dato?
引用符( ’ ) はWord内でさまざまなコードを持っています。確実に検索するために、
Word内の引用符をコピーして検索・置換のテキストボックスに貼りつけてください。
連続する2文字の繰り返しは次のように指定します。
結果:ワイルドカード:(??)¥1 / 正規表現: (..)¥2 どんどんと
70
ワイルドカードでは、(??)が 2 文字を示し、これを繰り返すために¥1 で示します。一 方、正規表現では、(..)が2文字を示し、これを2回繰り返すことを示すために¥2を使 います。
(d)コード
Sub ●ワード検索置換式()
For i = 0 To UBound(検索置換式$)
If 検索置換式$(i) = "" Then 検索置換式数% = i - 1: Exit For
If InStr(検索置換式$(i), "=>") Then '置換式ならば…
検索$(i) = Left$(検索置換式$(i), InStr(検索置換式$(i), "=>") - 1) 置換$(i) = Mid$(検索置換式$(i), InStr(検索置換式$(i), "=>") + 2) Else '検索式ならば…
検索$(i) = 検索置換式$(i) End If
Next End Sub
Sub ▼ワード検索置換()
Selection.Find.ClearFormatting '検索初期化
Selection.Find.Replacement.ClearFormatting '置換初期化
With Selection.Find '選択範囲検索
.Replacement.Highlight = chk蛍光色 '置換蛍光ペン
If chk文字色 Then .Replacement.Font.Color = BGR$(txt文字色値)
If chk下線色 Then
.Replacement.Font.Underline = wdUnderlineWavy
.Replacement.Font.UnderlineColor = BGR$(txt下線色値) End If
.Replacement.Font.Bold = chk太字
.MatchWildcards = CBool(cbo検索.ListIndex = 3) 'ワイルドカード
.MatchCase = IIf(cbo検索.ListIndex = 3, True, chk大小文字区別) '大小文字区別
71 .Format = True '書式を含む
.MatchWholeWord = False '完全単語一致をしない .MatchByte = False '全角半角文字を区別しない .MatchPhrase = False '単語間の空白文字を無視しない .MatchSoundsLike = False '類似単語検索をしない .MatchFuzzy = False '曖昧検索をしない
.MatchAllWordForms = False '活用形検索をしない
.Wrap = wdFindStop '末尾で検索終了 End With
For i = 0 To 検索置換式数%
Selection.Find.Text = 検索$(i)
Selection.Find.Replacement.Text = 置換$(i)
Selection.Find.Execute Replace:=wdReplaceAll '全置換 Next
Selection.Find.ClearFormatting '検索初期化
Selection.Find.Replacement.ClearFormatting '置換初期化 End Sub
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$ = Replace(W$, ".", "?") '正規表現の任意の1文字をワイルドカード式に W$ = Replace(W$, "@@!!", ".") '.を復元
72
W$ = Replace(W$, "¥&", "@@!!") '&をエスケープ W$ = Replace(W$, "&", "¥l+") '単語文字1以上 W$ = Replace(W$, "@@!!", "&") '&を復元
W$ = Replace(W$, "¥+", "@@!!") '+をエスケープ
W$ = Replace(W$, "+", "{1,}") '任意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", "[" & ChrW(&H400) & "-" & ChrW(&H52F) & "]") '拡張キリル文字
W$ = Replace(W$, "I", "[!" & ChrW(&H400) & "-" & ChrW(&H52F) & "]") '拡張キリル文字以外
W$ = Replace(W$, "¥g", "[" & ChrW(&H370) & "-" & ChrW(&H3FF) _ & ChrW(&H1F70) & "-" & ChrW(&H1F73) & "]") 'ギリシャ文字 W$ = Replace(W$, "¥G", "[!" & ChrW(&H370) & "-" & ChrW(&H3FF) _ & ChrW(&H1F70) & "-" & ChrW(&H1F73) & "]") 'ギリシャ文字
W$ = Replace(W$, "¥e", "[" & ChrW(&HAC00) & "-" & ChrW(&HD7AF) & "]") 'ハングル
W$ = Replace(W$, "¥E", "!" & ChrW(&HAC00) & "-" & ChrW(&HD7AF) & "]") 'ハングル以外
W$ = Replace(W$, "¥y", "[" & ChrW(&H3300) & "-" & ChrW(&H9FAF) & "]")
'CJK互換漢字、統合漢字、漢字拡張文字
W$ = Replace(W$, "¥Y", "[!" & ChrW(&H3300) & "-" & ChrW(&H9FAF) & "]")
73
'CJK互換漢字、統合漢字、漢字拡張文字以外
W$ = Replace(W$, "¥v", "[AEIOUaeiou" _
& ChrW(&HC0) & ChrW(&HC1) & ChrW(&HC2) _
& ChrW(&HC8) & ChrW(&HC9) & ChrW(&HCA) & ChrW(&HCB) _ & ChrW(&HCC) & ChrW(&HCD) & ChrW(&HCE) & ChrW(&HCF) _ & ChrW(&HD2) & ChrW(&HD3) & ChrW(&HD4) & ChrW(&HD5) _ & ChrW(&HD9) & ChrW(&HDA) & ChrW(&HDB) & ChrW(&HDC) _
& ChrW(&HE0) & ChrW(&HE1) & ChrW(&HE2) & ChrW(&HE3) & ChrW(&HE4) _ & ChrW(&HE8) & ChrW(&HE9) & ChrW(&HEA) & ChrW(&HEB) _
& ChrW(&HEC) & ChrW(&HED) & ChrW(&HEE) & ChrW(&HEF) _
& ChrW(&HF2) & ChrW(&HF3) & ChrW(&HF4) & ChrW(&HF5) & ChrW(&HF6) _ & ChrW(&HF9) & ChrW(&HFA) & ChrW(&HFB) & ChrW(&HFC) & "]") '母音文 字
W$ = Replace(W$, "¥V", "[!AEIOUaeiou" _
& ChrW(&HC0) & ChrW(&HC1) & ChrW(&HC2) _
& ChrW(&HC8) & ChrW(&HC9) & ChrW(&HCA) & ChrW(&HCB) _ & ChrW(&HCC) & ChrW(&HCD) & ChrW(&HCE) & ChrW(&HCF) _ & ChrW(&HD2) & ChrW(&HD3) & ChrW(&HD4) & ChrW(&HD5) _ & ChrW(&HD9) & ChrW(&HDA) & ChrW(&HDB) & ChrW(&HDC) _
& ChrW(&HE0) & ChrW(&HE1) & ChrW(&HE2) & ChrW(&HE3) & ChrW(&HE4) _ & ChrW(&HE8) & ChrW(&HE9) & ChrW(&HEA) & ChrW(&HEB) _
& ChrW(&HEC) & ChrW(&HED) & ChrW(&HEE) & ChrW(&HEF) _
& ChrW(&HF2) & ChrW(&HF3) & ChrW(&HF4) & ChrW(&HF5) & ChrW(&HF6) _ & ChrW(&HF9) & ChrW(&HFA) & ChrW(&HFB) & ChrW(&HFC) & "]") '母音文 字以外
W$ = Replace(W$, "¥c", "[BCDFGHJ-NP-TV-Zbcdfghj-np-tv-z" _
& ChrW(&HC7) & ChrW(&HD1) & ChrW(&HDF) & ChrW(&HEF) & ChrW(&HF1) &
"]")
'子音文字
W$ = Replace(W$, "¥C", "[!BCDFGHJ-NP-TV-Zbcdfghj-np-tv-z" _
& ChrW(&HC7) & ChrW(&HD1) & ChrW(&HDF) & ChrW(&HEF) & ChrW(&HF1) &
"]")
'子音文字以外
W$ = Replace(W$, "¥h", "[ぁ-ゞ]") 'ひらがな
74
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
最長一致と最短一致
アステリスク(*)やプラス(+)を使うと繰り返しを最大の範囲まで拡張して一致 します。これは最長一致と呼ばれます。一方、検索にはむしろ最小の範囲で一致 した方が都合がよいことがあります。これは最小一致と呼ばれます。そのときは アステリスク(*)やプラス(+)の後に '?' をつけると最長一致から最短一致に変わり ます。
たとえば、次の文字列を対象としましょう。
xxMxxMxxxMxxZxxxZxxxxxxxZxx 一致には次の4つのケースが考えられます。
(1) 最左最長一致 leftmost-longest match 検索式:M.*Z
xx<*MxxMxxxMxxZxxxZxxxxxxxZ*>xx (2) 最左最短一致(leftmost-shortest match)
検索式:M.*?Z
xx<*MxxMxxxMxxZ*>xxxZxxxxxxxZxx (3) 最右最長一致(rightmost-longest match)
検索式:M[^M]*Z
xxMxxMxxx<*MxxZxxxZxxxxxxxZ*>xx
75 (4) 最右最短一致(rightmost-shortest match) 検索式:M[^M]*?Z
xxMxxMxxx<*MxxZ*>xxxZxxxxxxxZxx
(1)では、検索式の「.*」が任意の文字がゼロ個以上あることを示し、それが最 初に(最左で)一致する部分から最大限まで拡張して一致しています。そこで、(2) では「?」をつけて最短一致させると、最初に一致する(最左の)部分から最短で 一致します。次に、(3)では「[^M]*」により M 以外の文字の連続を指定すると、
途中で M が現れることを防ぎ、検索は最右から始まります。ここで「[^M]*」は 最長一致するので、さらに(4)で「?」をつけて真の最短一致をさせます。一致の開 始点が2文字以上のときは次のように「(...)」でグループ化します。
検索式:MN[^(MN)]*?Z
xxMNxxMNxxx<*MNxxZ*>xxxZxxxxxxxZxx
このように厳密に最短一致で検索するときは細かな指定が必要ですが、実際に は(2)の最左最短一致で十分です。TEXTOSではこの場合 M**Z という検索式を使 います。