ダウンロード

正規表現を利用したユーザー定義関数

エクセルでの正規表現は、「*」(任意の0個以上の文字列)、「?」(任意の1個以上の文字)くらいしか使用できませんが、 VBAの正規表現を利用すると、かなり複雑な形式の表現で検索/置換を行うことができます。
例:"[0-9A-F]{2}" → 0-9とA-Fのいずれかの2文字(2桁の16進数)
ここでは、使い易くする為に、ユーザー定義関数として登録します。

メニュー
検索 - MyRegText
個数取得 - MyRegCount
置換 - MyRegReplace
使用例
関数登録処理
サンプルファイルのダウンロード
関連
リンクリスト



文字列検索 - MyRegText

書式 MyRegText(対象文字列,パターン,取得位置)

正規表現で文字列中から指定の文字列を検索し、見つかったら、その文字列を返す

パラメータ
対象文字列 検索対象文字列
パターン 検索する文字列を正規表現で指定(正規表現の記述方法
取得位置 複数ある場合に、その番目を指定(1〜)、省略時は1番目
戻り値

見つかった文字列、見つからなかった場合は空白。


VBAコード
Function MyRegText(対象文字列 As String, パターン As String, Optional 取得位置 As Integer = 1) As String
'
' 正規表現による検索
'
' 入力
'  対象文字列:対象文字列
'  パターン  :検索正規表現パターン
'  取得位置  :取得するマッチ番号(1〜)
'
' 戻り値   :見つかった文字列
'
    MyRegText = ""
    
    Dim reMatch As MatchCollection 'マッチ結果格納用オブジェクト
    Dim reSubMatches As SubMatches 'サブマッチコレクション格納用

    With re
        .Pattern = パターン
        .IgnoreCase = True      '大小文字の区別無し
        .Global = True          '文字列全体を検索
        If re.Test(対象文字列) Then    'テスト マッチ?
            Set reMatch = .Execute(対象文字列)
            If reMatch.Count >= 取得位置 Then
                Set reSubMatches = reMatch.Item(取得位置 - 1).SubMatches
                If reSubMatches.Count > 0 Then
                    MyRegText = reSubMatches(0)
                Else
                    MyRegText = reMatch.Item(取得位置 - 1) 'マッチ文字列
                End If
            End If
        End If
    End With
    
End Function

正規表現オブジェクトを使用するため、「参照設定」をしておく必要があります。
(CreateObjectで作成すれば参照設定の必要は無いが、入力チェックや支援が行われないので設定した方が便利。)



MyRegText(E15,"^.{2,3} [都道府県]")

^        :行頭を表す。この場合、対象文字列の先頭
.         :任意の1文字
{2,3}    :直前に指定した正規表現(本例では「.」)が2文字以上3文字以内で連続
[都道府県]:[ ]内に記述されたいずれかの1文字

^.{2,3}[都道府県]:対象文字列の先頭から2、3文字の後に続く、都道府県のいずれかの1文字まで


MyRegText(E15,"^.{2,3} [都道府県](.*)")

これは、都道府県の後に続く文字列を取り出している。

( ):グループ化。括弧がある場合、その括弧の内側の文字列が取り出される。
*  :0個以上の繰り返し
.* :任意の文字が0個以上続く

都道府県分割

MyRegText("0"&$B8&"0","0([^0]{4})0",2)

この例は、0以外の文字が4個連続する文字列の2番目の文字列を取り出している。
下図の例では、4441 , 4442 , 4443 の3個が存在するので、2番目は、4442 となる。

[^0]        :0以外の1文字。[]内の「^」は否定を表す。
[^0]{4}     :0以外の文字が4個連続
0([^0]{4})0 :両端が「0」である「0」以外の連続する4文字

対象文字列を"0"&$B7&"0" としているのは、探す文字列が先頭、または末尾にある場合の対処。
端にある場合は「0」で挟まれていないので、対象文字列の両端に「0」を付加している。

指定番目を抽出

個数取得 - MyRegCount

書式 MyRegCount(対象文字列,パターン)

正規表現で文字列中から指定の文字列を検索し、みつかった文字列の個数を返す
(注:文字列の長さではない)

パラメータ
対象文字列 検索対象となる文字列
パターン 検索する文字列を正規表現で指定(正規表現の記述方法
戻り値

見つかった文字列の個数、見つからなかった場合は0。

Function MyRegCount(対象文字列 As String, パターン As String) As Integer
'
' 正規表現による検索
'
' 入力
'  対象文字列:対象文字列
'  パターン  :検索正規表現パターン
'
' 戻り値   :見つかった個数
'
    MyRegCount = 0
    
    Dim reMatch As MatchCollection 'マッチ結果格納用オブジェクト
    
    With re
        .Pattern = パターン
        .IgnoreCase = True      '大小文字の区別無し
        .Global = True          '文字列全体を検索
        If re.Test(対象文字列) Then    'テスト マッチ?
            Set reMatch = .Execute(対象文字列) '発見
            MyRegCount = reMatch.Count  'マッチ個数セット
        End If
    End With
    
End Function

MyRegCount("0"&$B7&"0","0([^0]{4})0")

この例は、0以外の文字が4個連続する文字列の個数を調べている。
下図の例では、4441 , 4442 , 4443 の3個が存在するので、3が返っている

[^0]        :0以外の1文字。[]内の「^」は否定を表す。
[^0]{4}     :0以外の文字が4個連続
0([^0]{4})0 :両端が「0」である「0」以外の連続する4文字

対象文字列を"0"&$B7&"0" としているのは、探す文字列が先頭、または末尾にある場合の対処。
端にある場合は「0」で挟まれていないので、対象文字列の両端に「0」を付加している。


MyRegCount ("0"&$B18&"0","[^休]休{2}[^休]")

シフト表を模した文字列から、2連休の個数を求めている。

対象文字列を"0"&$B18&"0" としているのは、前項と同じく、探す文字列が先頭、または末尾にある場合の対処


MyRegCount("休"&$B18&"休","休[^休]{3}休")

シフト表を模した文字列から、3日連続する勤務を求めている(注:4連勤以上は含まない)
「休」に挟まれた「休」以外の連続する3個の文字列

連続文字の個数

正規表現の記述方法
文章中の特定文字列の個数を算出する方法
標準機能の数式のみで都道府県名を取り出す方法

使用例

ファイル名取得

ファイルパスから、フォルダパス、ファイル名を正規表現関数 MyRegText で取り出してみます。

フォルダパスを取得する正規表現



  ^(.+)¥¥.+?$

  ^ :行頭  $:行末
  .+ :1文字以上の任意の文字列
  ¥¥:円記号(メタ文字なので「¥」でエスケープする)
  ¥¥.+?$ :円記号から行末までの1文字以上の最短マッチ
  ( ):グループ化。このカッコ内の文字列が取得される。


ファイル名を取得する正規表現

 .*¥¥(.+?)$

  ¥¥ :円記号(メタ文字なので「¥」でエスケープする)
  .* :0文字以上の任意の文字列
  .+? :1文字以上の最短マッチ
  $ :行末
  


文字列置換

書式 MyRegReplace(対象文字列,パターン,置換文字列)

正規表現で文字列中から指定の文字列を検索し、みつかった文字列を置換文字列で置き換えます。

パラメータ
対象文字列 検索対象となる文字列
パターン 検索する文字列を正規表現で指定(正規表現の記述方法
置換文字列 置換する文字列
戻り値

置換後の文字列

Public Function MyRegReplace(ByVal 対象文字列 As String, ByVal パターン As String, ByVal 置換文字列 As String) As String
'
' 正規表現による置換
'
'    対象文字列:対象となる文字列
'    パターン  :検索正規表現パターン
'    置換文字列:置換する文字列
'
    MyRegReplace = 対象文字列
    
    Dim reMatch As MatchCollection 'マッチ結果格納用オブジェクト
    Dim reSubMatches As SubMatches 'サブマッチコレクション格納用

    With re
        .Pattern = パターン
        .IgnoreCase = True      '大小文字の区別無し
        .Global = True          '文字列全体を検索
        If re.Test(対象文字列) Then    'テスト
            Set reMatch = .Execute(対象文字列) '発見
            MyRegReplace = re.Replace(対象文字列, 置換文字列)   '置換
        End If
    End With
    
End Function

関数登録処理

関数を使用するにあたって、概要パラメータの説明ヘルプへのリンクなどを登録します。
これにより、関数を使用する時、かなり使いやすくなります。

下記の処理は、ブックを開く時のイベント処理「Workbook_Open」から呼び出されます。

なお、これらの詳細については、「ユーザー定義関数の作り方」を参照。
Sub RegisterMyFunction()
    Application.MacroOptions Macro:="MyRegText", Description:="正規表現によりパターンにマッチする文字列を検索します", _
    Category:="文字列操作", ArgumentDescriptions:=Array("対象文字列", "正規表現パターン", "取得するマッチ番号(1〜)"), _
    HelpFile:="../../../../kyozai/excel_vba/300_vba_kiso/80_regex/index.htm?MyRegText"

    Application.MacroOptions Macro:="MyRegCount", Description:="正規表現によりパターンにマッチした個数を返します。", _
    Category:="文字列操作", ArgumentDescriptions:=Array("対象文字列", "正規表現パターン"), _
    HelpFile:="../../../../kyozai/excel_vba/300_vba_kiso/80_regex/index.htm?MyRegCount"
    
    Application.MacroOptions Macro:="MyRegReplace", Description:="正規表現によりパターンにマッチする文字列を検索します", _
    Category:="文字列操作", ArgumentDescriptions:=Array("対象文字列", "正規表現パターン", "置換後の文字列"), _
    HelpFile:="../../../../kyozai/excel_vba/300_vba_kiso/80_regex/index.htm?MyRegRep"
End Sub
  


関連


×
PageTop