(0)目次&概説
(1) 正規表現とは
(2) 正規表現はどのような場面で利用される?
(3) VBAによる正規表現の簡易チェックツール
(3-1) 郵便番号を抽出したい
(3-2) 正規表現が正しいかをチェックする
①ツール使用例
②ソースコード紹介
(3-3) 抽出した郵便番号を置換したい
①ツール使用例
②ソースコード紹介
(1) 正規表現とは
正規表現とは、特定のパターンにマッチする文字列のグループを一つの文字列で集約して表す方法で、英語では”Regular Expression”と呼びます。
>目次にもどる
(2) 正規表現はどのような場面で利用される?
例えば、大量の文字列の中から「郵便番号」を探したいケースがあるとします。一般的に郵便番号は「NNN-NNNN」のような「数字3桁」+「ハイフン」+「数字4桁」で記載されるのケースが多いですが、場合によっては先頭に「〒」が付いたり、ハイフンが無く数字7桁であったり形式は様々なので、漏れなく探すのは案外難しいケースがあると思います。そうしたケースに「特定のパターン」に合致する文字列を探せる正規表現を利用する事で、ある程度の幅を持たせた探索が可能となります。それを活かして、一括で置換処理などを行う事ができると思います。
>目次にもどる
(3) VBAによる正規表現の簡易チェックツール
VBAで正規表現を利用するためには「VBScript.RegExp」オブジェクトを利用しますが、そのために以下の事前設定(拡張機能の追加)を行います。
①開発タブから「Visual Basic」のウィンドウを開く
②ツールから参照設定を開く
③「Microsoft VBScript Regular Expressions 5.5」にチェックを入れる
以上で事前準備は完了です。
(3-1) 郵便番号を抽出したい
冒頭で記載した通り、郵便番号には以下の3パターンがあると想定します。これに対応できる正規表現を考えていきます。
(パターン1)数字3桁+ハイフン+数字4桁のパターン(NNN-NNNN)
(パターン2)先頭に「〒」が付くパターン(〒NNN-NNNN)
(パターン3)数字7桁のパターン(NNNNNNN)
(Step1)最もスタンダードなパターンの考慮
まずは「数字3桁+ハイフン+数字4桁」の正常系(パターン1)を考えると以下のようになります。
\d{3}-\d{4}
(Step2)桁数を正しく制御
しかし、これだけでは前半が3桁以上or後半が4桁以上の場合も含まれてしまいます。つまり、7桁以上の数字を含む不要なパターンも混在してしまいます。
正規表現 | チェック対象 | 判定 | 備考 |
\d{3}-\d{4} | 1234-5678 | TRUE | 異常系 |
\d{3}-\d{4} | 123-45678 | TRUE | 異常系 |
\d{3}-\d{4} | 1234-567 | FALSE | 異常系 |
\d{3}-\d{4} | 1234-56789 | TRUE | 異常系 |
これを防止するために、以下のように修正します。
^\d{3}-*\d{4}$
すると、結果は以下のように7桁以上のものはFALSE(マッチしない)になります。
正規表現 | チェック対象 | 判定 | 備考 |
^\d{3}-*\d{4}$ | 1234-5678 | FALSE | 異常系 |
^\d{3}-*\d{4}$ | 123-45678 | FALSE | 異常系 |
^\d{3}-*\d{4}$ | 1234-567 | FALSE | 異常系 |
^\d{3}-*\d{4}$ | 1234-56789 | FALSE | 異常系 |
(Step3)〒の考慮
次に先頭に「〒」が付くケース(パターン2)を考えます。「〒」は付く場合と付かない場合があるので、その点を考慮すると以下のようになります。
^〒*\d{3}-*\d{4}$
テスト結果は以下のようになります。
正規表現 | チェック対象 | 判定 | 備考 |
^〒*\d{3}-*\d{4}$ | 123-4567 | TRUE | 正常系 |
^〒*\d{3}-*\d{4}$ | 〒123-4567 | TRUE | 正常系 |
^〒*\d{3}-*\d{4}$ | 1234-5678 | FALSE | 異常系 |
^〒*\d{3}-*\d{4}$ | 123-45678 | FALSE | 異常系 |
^〒*\d{3}-*\d{4}$ | 1234-567 | FALSE | 異常系 |
^〒*\d{3}-*\d{4}$ | 1234-56789 | FALSE | 異常系 |
各要素の意味をまとめると以下のようになります。
① | ^ | 直後の「〒」文字が行の最初にあれば一致。 |
② | * | 直前の「〒」文字を0回以上繰り返し(0回も許容するため、出現しない場合もOK) |
③ | \d | 数字([0-9]と同じ意味) |
④ | {3} | 直前の文字を3回繰り返す |
⑤ | – | ハイフン |
⑥ | * | 直前の「-」文字を0回以上繰り返し(0回も許容するため、出現しない場合もOK) |
⑦ | \d | 数字([0-9]と同じ意味) |
⑧ | {4} | 直前の文字を4回繰り返す |
⑨ | $ | 直前の文字が行の最後にあれば一致(※今回の場合”[0-9]”の文字) |
(3-2) 正規表現が正しいかをチェックする
上記で作成した正規表現が正しいかをチェックするためにも、いよいよVBAの「VBScript.RegExp」オブジェクトが登場します。以下に示すプログラムは引数に「正規表現」と「チェックしたい文字列」を入力し、正規表現にマッチする場合は”TRUE”を返し、マッチしない場合は”FALSE”を返す関数です。使い方は通常のエクセルの関数と同様に、以下のような式でチェックができます。
=RegularExpressionCheck([正規表現],[チェックしたい文字列])
●使用例
●ソースコード
'変数の宣言を省略させないようにする Option Explicit Function RegularExpressionCheck(Condition As String, TestWord As String) Dim Reg As Variant Dim Flag As Boolean '正規表現のオブジェクト作成 Set Reg = CreateObject("VBScript.RegExp") '①検索する正規表現をFunctionの引数から代入 Reg.Pattern = Condition '②大文字と小文字を区別しない場合はTrueをセット '(デフォルトはFalseに設定されている) Reg.IgnoreCase = False '③文字列の最初の1ヶ所のみならず全体の一致チェックをする場合 Reg.Global = True '④指定した文字列が正規表現にマッチするかどうか返す Flag = Reg.Test(TestWord) Set Reg = Nothing RegularExpressionCheck = Flag End Function
(3-3) 抽出した郵便番号を置換したい
次に正規表現にマッチする文字列を、別の文字列に置き換えたい場合です。こちらも「VBScript.RegExp」オブジェクトの「Replace」プロパティを利用します。 以下に示すプログラムは②の文字の中から①の正規表現にマッチする部分を③で置き換える、という処理を行います。 引数に「①正規表現」と「②被置換文字列」と「③正規表現にマッチした場合の置き換え後文字列」の3つを指定します。
=RegularExpressionCheck([①正規表現],[②被置換文字列],[③正規表現にマッチした場合の置き換え後文字列])
●使用例
●ソースコード
Function RegularExpressionReplace(Text As String, Condition As String, ReplaceWord As String) Dim Reg As Variant Dim AfterReplace As String '正規表現のオブジェクト作成 Set Reg = CreateObject("VBScript.RegExp") '①検索する正規表現をFunctionの引数から代入 Reg.Pattern = Condition '②大文字と小文字を区別しない場合はTrueをセット '(デフォルトはFalseに設定されている) Reg.IgnoreCase = False '③文字列の最初の1ヶ所のみならず全体の一致チェックをする場合 Reg.Global = True '④任意の文字列から"Condition"で指定した正規表現にマッチする文字列について、"ReplaceWord"で指定した文字に置き換える AfterReplace = Reg.Replace(Text, ReplaceWord) RegularExpressionReplace = AfterReplace End Function
↓★以下、オススメの書籍です。