?をまとめて置換する

昨日は、当ブログを訪れた方の検索キーワード
vba 正規表現 ?で区切られた文字列 抽出」
を少しだけ掘り下げて、実際に正規表現で抽出するマクロを考えてみた。
infoment.hatenablog.com
そこで今回は、昨日の続きを少しだけ紹介する。
f:id:Infoment:20190204223402p:plain
(↑ Canvaで「一度に」で検索したら出てきた画像。)

さて、昨日は「?以外」を正規表現で抽出することで、欲しい文字列だけを表示させてみた。

Sub 区切りテスト_正規表現()
    Dim str As String
        str = "A?B?CDE?F"
        
    ' 正規表現
    Dim myReg As RegExp
    Set myReg = New RegExp
    ' パターン設定。「?」以外の文字を表す。
        myReg.Pattern = "[^\?]+"
    ' マッチする全ての場合を抽出。
    ' ※一個見つけても中断しない。
        myReg.Global = True
    
    ' strがパターンにマッチするならば、
        If myReg.Test(str) Then
            Dim MatchCases As MatchCollection
    ' マッチするものを全て取得する(マッチコレクション)。
            Set MatchCases = myReg.Execute(str)
            Dim m As Variant
    ' マッチするものを一つずつ取り出して、イミディエイトに表示。
            For Each m In MatchCases
                Debug.Print m
            Next
        End If
End Sub

今回は逆に、「?」を正規表現で引っ掛けてみる。
作戦は、↓ こうだ。

  1. 正規表現で、連続する「?」が存在するかを確認する。
  2. 存在する場合、単独の「?」に置換する。

区切り文字としての「?」が一個ずつしかないならば、split関数が使用できる。
こんな感じで。

Sub 区切りテスト_正規表現()
    Dim str As String
        str = "A?B??CDE????F"

    ' 正規表現
    Dim myReg As RegExp
    Set myReg = New RegExp
    ' パターン設定。一回以上連続する「?」を表す。
        myReg.Pattern = "\?+"
        myReg.Global = True

    Dim seq As Variant
        If myReg.Test(str) Then
            str = myReg.Replace(str, "?")
            seq = Split(str, "?")
            MsgBox Join(seq, vbNewLine)
        End If
End Sub

昨日のものより、こちらの方が短くて済む。
状況と目的で、上手く使い分けられればと思う。

ちなみに置換するこの方式は、表現の揺らぎを矯正する場合にも有効だ。
こんな感じで、無節操この上ない区切り文字の乱用でも、きれいにアルファベットだけを取り出すことが出来る。

A?B.C,D-E_F:G;

Sub 区切りテスト_正規表現()
    Dim str As String
        str = "A?B.C,D-E_F:G;"

    Dim myReg As RegExp
    Set myReg = New RegExp
        myReg.Pattern = "[\?\.,\-_;:]"
        myReg.Global = True

        If myReg.Test(str) Then
            MsgBox myReg.Replace(str, vbNewLine)
        End If
End Sub

f:id:Infoment:20190204224921p:plain

これを自由自在に使いこなせれば格好いいのだけど、いつもパターンづくりで躓いています。

参考まで。