正規表現

正規表現とは

正規表現とは、文字列のパターンを表現する記法(ルール)のことをいいます。日本の郵便番号を例に考えてみます。例えば、「102-0073」という郵便番号は、3桁の数字、ハイフン、4桁の数字を組み合わせて作られています。正規表現を使ってこの郵便番号を表現すると、「\d{3}\-\d{4}」というパターンになります。このパターンを使い、ある文字列から郵便番号(のパターンに一致する文字列)を検索、置換、抽出することができます。

パターンに一致する文字列を実際に検索、置換、抽出するソフトウェアは正規表現エンジンといい、VBAで正規表現を使った文字列処理を行うには、この後に説明するVBScript Regular Expressions 5.5(正規表現エンジン)を使うのが一般的です。

Microsoft VBScript Regular Expressions 5.5

VBAで正規表現を使った文字列処理を行うにはMicrosoft VBScript Regular Expressions 5.5を使用します。次の手順にしたがってMicrosoft VBScript Regular Expressions 5.5への参照を設定します。

  1. VBAのエディターで[ツール]-[参照設定]をクリックします。
  2. [参照可能なライブラリファイル]でMicrosoft VBScript Regular Expressions 5.5にチェックを入れます。
  3. [OK]をクリックして[参照設定]ダイアログを閉じます。

文字列の検索

次のサンプルコードは、変数 address の中の郵便番号にマッチする文字列を検索し、見つかった場合に「郵便番号が見つかりました。」とメッセージを表示します。

Sub Example4()

    Dim address As String
    address = "〒 102-0073 東京都千代田区九段北一丁目"
    
    Dim regx As RegExp
    Set regx = New RegExp
    regx.Pattern = "\d{3}\-\d{4}"
    
    If (regx.Test(address)) Then
        MsgBox "郵便番号が見つかりました"
    End If
    
    Set regx = Nothing
    
End Sub

文字列の置換

次のサンプルコードは、変数 phone の中の電話番号の末尾4桁を xに置き換えます。

Sub Example5()

    Dim phone As String
    phone = "電話番号は42-9324です。"
    
    Dim regx As RegExp
    Set regx = New RegExp
    regx.Pattern = "\d"
    regx.Global = True
    
    phone = regx.Replace(phone, "x")
    
    Set regx = Nothing
    
    MsgBox phone
    
End Sub

文字列の抽出

次のサンプルコードは、変数 phone の中の数字を一文字ずつ抽出します。

Sub Example6()

    Dim phone As String
    phone = "電話番号は42-9324です。"
    
    Dim regx As RegExp
    Dim m As Match
    Dim ms As MatchCollection
    
    Set regx = New RegExp
    regx.Pattern = "\d{1}"
    regx.Global = True
    
    Set ms = regx.Execute(phone)
    
    For Each m In ms
        MsgBox m.Value
    Next
    
    Set regx = Nothing
    
End Sub

よく使うパターン

かっこの中の数値を取り出す

次のサンプルコードは、かっこの中の数値だけを取り出します。

Sub Example8()

    Dim x As String
    x = "(-3.14)"
    
    Dim regx As RegExp
    Dim m As Match
    Dim ms As MatchCollection
    
    Set regx = New RegExp
    regx.Pattern = "-*\d+\.?\d*"
    regx.Global = True
    
    Set ms = regx.Execute(x)
    
    For Each m In ms
        MsgBox m.Value
    Next
    
    Set regx = Nothing
    
End Sub

URLの中のドメイン名を取り出す

Sub Example53()
    Dim url As String
    url = "http://www016.upp.so-net.ne.jp/cheetah/xlvba/VBA/Programming10.html"
    
    url = ExtractDomain(url)
    MsgBox url

End Sub

Function ExtractDomain(url As String) As String

    '' オブジェクト変数を宣言する。
    Dim regex As Object
    '' VBScriptの正規表現オブジェクトのインスタンスを作成する。
    Set regex = CreateObject("VBScript.RegExp")
    regex.Global = True
    regex.IgnoreCase = True
    
    Dim s As String
    
    '' http://またはhttps://を取り除く。
    regex.Pattern = "^https?://"
    s = regex.Replace(url, "")
    
    '' ドメイン名以外のパス部分を取り除く。
    regex.Pattern = "/.*$"
    s = regex.Replace(s, "")
    
    '' 残りの部分からドメイン名を取り出す。
    Dim domainJapanese As String
    Dim domainGlobal As String
    Dim domain As String
    
    domainJapanese = "(ac|ad|co|ed|go|gr|lg|ne|or)?\.?jp+"
    domainGeneric = "(com|net|org|gov|mil|edu)+"
    domain = "(" + domainJapanese + "|" + domainGeneric + ")"
    
    regex.Pattern = "[^\.]+\." + domain
    
    Dim m As Object
    Dim ms As Object
    
    '' ドメイン部分をMatchCollectionに代入する。
    Set ms = regex.Execute(s)
    
    For Each m In ms
        ExtractDomain = m.Value
    Next
    
    Set m = Nothing
    Set ms = Nothing
    Set regex = Nothing

End Function
Example53 の実行結果
Example53 の実行結果

文字列にカタカナが含まれているか判定する

次のサンプルコードは、文字列にカタカナが含まれているか判定します。

Sub Example47()

    Dim regx As New RegExp
    regx.Pattern = "[\u30A0-\u30FF]+"
    
    '' ひらがな:[\u3040-\u309F]
    '' 漢字:[\u4E00-\u9FFF]
    
    Dim s As String
    s = "ベースボール"
    
    If (regx.Test(s)) Then
        MsgBox "文字列にカタカナ文字が含まれています。"
    End If
    
    Set regx = Nothing

End Sub

よく使う文字クラス

よく使う文字クラス
記号 意味
[xyz] 角カッコの中の任意の1文字にマッチします。
[^xyz] 角カッコの中に含まれていない任意の1文字にマッチします。
. ¥n(改行)以外の任意の1文字にマッチします。
¥w アルファベット(大文字と小文字)、数字、アンダースコアの任意の1文字にマッチします。
¥W アルファベット(大文字と小文字)、数字、アンダースコア以外の任意の1文字にマッチします。
¥d 任意の数字にマッチします。
¥D 任意の数字以外の文字にマッチします。
[¥u3040-¥u309F] ひらがなの任意の1文字にマッチします。
[¥u30A0-¥u30FF] カタカナの任意の1文字にマッチします。
[¥u4E00-¥u9FFF] 漢字の任意の1文字にマッチします。

Global プロパティ

RegExpオブジェクトにGlobalというプロパティがあります。このプロパティを使うと、パターンにマッチする文字列をすべて検査するかどうかを切り換えることができます。

次のサンプルコードは、正規表現を使ってパターンに一致する文字列をメッセージボックスで表示します。このサンプルコードでは、検査される文字列を"ABCD"、パターンを"[A-Z]"とします。"[A-Z]"は大文字のアルファベット、一文字とマッチするパターンです。Globalプロパティの違いによって、実行結果に次のような違いがあります。

Sub Example28()

    '' 検査される文字列
    Dim s As String
    s = "ABCD"
    
    '' 正規表現オブジェクトを作成する
    Dim regx As New RegExp
    
    '' パターンはアルファベット大文字で、一文字とする
    regx.Pattern = "[A-Z]"
    regx.Global = True
    
    '' パターンに一致する文字を取得する
    Dim m As Match
    Dim ms As MatchCollection
    Set ms = regx.Execute(s)
    
    '' パターンに一致した文字をメッセージボックスで表示する
    For Each m In ms
        MsgBox m.Value
    Next
    
    '' オブジェクト変数にNothingを代入する
    Set ms = Nothing
    Set regx = Nothing

End Sub
Global値による実行結果の違い
Globalの値 実行結果
True "A", "B", "C", "D" の4文字とマッチする。
False "A" の1文字とマッチする。

IgnoreCase プロパティ

IgnoreCaseプロパティを使うと、アルファベットの大文字と小文字を区別するのかどうかを切り換えることができます。IgnoreCase プロパティをFalseにすると、アルファベットの大文字と小文字を区別しないで検査します。既定値はFalseです。

最短一致

<h1>Welcome</h1>という文字列のHTMLタグだけに一致させたいことは、よくあることだと思います。この文字列に対して、"<.+>"というパターンで判定すると、文字列全体が一致してしまいます。そのような場合、パターン文字列を"<.+?>"にすると、HTMLタグだけに一致するようになります。

最短一致
検査する文字列 パターン 一致する文字列
<h1>Welcome</h1> <.+> <h1>Welcome</h1> に一致する
<.+?> <h1> と </h1> に一致する
Sub Example48()

    Dim regx As New RegExp
    regx.Pattern = "<.+?>"
    regx.Global = True
    
    Dim html As String
    html = "<h1>Welcome</h1>"
    
    Dim m As Match
    Dim ms As MatchCollection
    
    Set ms = regx.Execute(html)
    
    For Each m In ms
        MsgBox m.Value
    Next
    
    Set m = Nothing
    Set ms = Nothing
    Set regx = Nothing

End Sub

参考リンク