こんにちは、Ryoです。
ExcelVBAでは文字列の検索や置換を行うことは多いので、複数の文字列を一つの形式で表現できる正規表現を利用すると便利です。今回はCreateObject関数でRegExpオブジェクトによる存在チェック/検索/置換する方法について書いていきます。
1.正規表現の利用とTestメソッド
正規表現を利用するには、CreateObject関数の引数classに「VBScript.RegExp」を指定しますので、その方法に準じて各サンプルコードなどを書いています。
構文:CreateObject(class,[servername])
他には「Microsoft VBScript Regular Expression 5.5」を参照設定する方法もありますが、こちらは割愛します。
先ず簡単なサンプルとして、セルA1に入力された文字列に対し「先頭が数値かどうか」を確認し、結果をメッセージボックスで表示します。
予めセルA1の表示形式を「文字列」にしておきます。
そこに「012345」と入力しサンプルを実行すると以下の通り、先頭文字を数値として判定(True)しています。
次に「x12345」と入力した場合は文字判定(False)になります。
◆サンプルコード(Sample1:Testメソッド)
Sub Sample1() '正規表現を使用し文字/数値を判定する '**Testメソッド** '正規表現を利用する為のオブジェクトを作成 With CreateObject("VBScript.RegExp") '文字列パターンを設定 '「^」=文字列先頭にマッチ、[0-9]=0~9数値指定 .Pattern = "^[0-9]" 'セルA1に入力された文字列が設定パターンに該当するかテストし '結果をメッセージボックスに表示 MsgBox "文字列「" & Cells(1, 1).Value & "」の先頭は数値?:" _ & .Test(Cells(1, 1).Value) & vbLf & vbLf _ & "True=数値 False=文字" End With End Sub
正規表現はVBScriptがサポートしている機能になりますので、先ずCreateObject関数でRegExpオブジェクトを作成し、Patternプロパティでチェックする文字列を設定します。
サンプルでは文字列パターンに「^[0-9]」を指定していますが、「^」は文字列の先頭にマッチすることを表し、[0-9]は0~9までの数値を表しますので、「先頭が数値である文字列にマッチする」ということになります。
後は指定パターンがあてはまるかどうかの存在チェックをTestメソッドで判定し、結果をメッセージボックスに表示させています。
構文:Test(string)
Testメソッドは引数stringに指定された文字列を検索し、正規表現とマッチで「True」、不一致で「False」を返します。
◆RegExpオブジェクト設定/文字列パターン
RegExpオブジェクトのプロパティやメソッド、正規表現で使用する文字列パターン詳細は以下の通りになります。
≪ RegExpオブジェクトのプロパティ≫
プロパティ | 内容 |
Pattern | 正規表現を定義する文字列でメソッド呼び出し前に設定する必要あり |
IgnoreCase | 大文字・小文字区別するかどうかを表し、True設定で大文字/小文字区別なし。初期値はFalse |
Global | ReplaceメソッドやExecuteメソッドを呼び出す際に複数マッチを行うかどうかを表し、True設定で正規表現にマッチする全ての部分に対して検索・置換を実行。初期値はFalse |
MultiLine | 文字列を複数行として扱うかどうかを表し、True設定で各行の先頭や末尾でも”^”や”$”がマッチする。初期値はFalse |
≪ RegExpオブジェクトのメソッド ≫
メソッド | 内容 |
Test(string) | 引数stringに指定された文字列を検索し正規表現とマッチする場合はTrue、一致しない場合はFalseを返す。 |
Replace(string1,string2) | 引数string1は検索や置換対象の文字列を指定、引数string2は置換する文字列を指定。 |
Execute(string) | 引数stringに指定した文字列を検索し、検索結果をMatchオブジェクトを含むMatchesコレクションとして返す。 |
MultiLine | 文字列を複数行として扱うかどうかを表し、True設定で各行の先頭や末尾でも”^”や”$”がマッチする。初期値はFalse |
≪ 正規表現で使用する文字列パターン ≫
パターン | 内容 |
^ | 文字列の先頭にマッチ |
$ | 文字列の末尾にマッチ |
\b | 単語の境界にマッチ |
\B | 単語の境界以外にマッチ |
\n | 改行にマッチ |
\f | フォームフィード(改ページ)にマッチ |
\r | キャリッジリターン(行頭復帰)にマッチ |
\t | 水平タブにマッチ |
\v | 垂直タブにマッチ |
\xxx | 8進数(シフトJIS)xxxによって表現される文字にマッチ。但しASCII文字以外には使用不可。 |
\xdd | 16進数(シフトJIS)ddによって表現される文字にマッチ。但しASCII文字以外には使用不可。 |
\uxxxx | Unicode(UTF-16)xxxxによって表現される文字にマッチ。 |
[] | ”[]”内に含まれている文字にマッチ。”_”による範囲指定も可。 |
[^ ] | “[^ ]内に含まれている文字以外にマッチ。”_”による範囲指定も可。 |
\w | 単語に使用される文字にマッチ。[a-zA-Z_0-9]と同じ。 |
\W | 単語に使用される文字以外の文字にマッチ。[^a-zA-Z_0-9]と同じ。 |
. | \n以外の文字にマッチ。全角文字にもマッチする。 |
\d | 数字にマッチ。[0-9]と同じ。 |
\D | 数字以外の文字にマッチ。[^0-9]と同じ。 |
\s | スペース文字にマッチ。[\t\r\n\v\f]と同じ。 |
\S | スペース文字以外の文字にマッチ。[^\t\r\v\n\f]と同じ。 |
{x} | 直前の文字のx回にマッチ。 |
{x,} | 直前の文字のx回以上にマッチ。 |
{x,y} | 直前の文字のx回以上、y回以下にマッチ。 |
? | 直前の文字の0または1回にマッチ。{0,1}と同じ。 |
* | 直前の文字の0回以上にマッチ。{0,}と同じ。 |
+ | 直前の文字の1回以上にマッチ。{1,}と同じ。 |
() | 複数の文字をグループ化し、ネストすることが可能。 |
| | 複数の文字列を1つの正規表現にまとめ、いずれかにマッチ |
2.正規表現の利用と文字列検索
次に文字列検索でのサンプルですが、サンプル1同様にセルA1に入力された文字に対して処理を行います。
画像に示す通りセルA1に「jizilog1.com jizilog2.com VBA」と文字が入力されていますので、アルファベットから始まり数字も含み「.com」で終わる文字列を検索します。
実行結果は以下になります。
該当なしの場合
◆サンプルコード(Sample2:Executeメソッド)
!注記! コード行13~19が使用しているプラグインの都合で正しく表示されていませんので、以下解説で貼り付けてあるスクリーンショットを参照ください。
Sub Sample2() '正規表現を使用して文字列を検索する '**Executeメソッド** Dim Re As Object Dim Mc As Object Dim msg As String Dim i As Long '正規表現を利用する為のRegExpオブジェクトを作成 Set Re = CreateObject("VBScript.RegExp") With Re '正規表現パターンの設定 '[A-Z,a-z,0-9]で全てのアルファベットと0~9範囲の数値 '「+」で直前に指定した文字の繰り返しを表す '[.][c][o][m]で「.com」という文字を表す 'この指定で「.com」で終わる文字列という意味になる .Pattern = "[A-Z,a-z,0-9]+[.][c][o][m]" '複数マッチを有効 .Global = True 'セルA1に入力された文字列に対して検索を実行する Set Mc = .Execute(Cells(1, 1).Value) End With With Mc '対象文字の有無を判定 If .Count > 0 Then For i = 0 To .Count - 1 '対象文字「有り」の場合、文字を取得 msg = msg & i + 1 & "番目の文字列:" & _ .Item(i).Value & vbLf Next Else '対象文字「なし」の場合の文字列 msg = "該当なし" End If End With 'メッセージボックスの表示 If msg = "該当なし" Then MsgBox msg, vbCritical Else MsgBox msg, vbInformation End If End Sub
このように正規表現を利用した文字列の検索にはExecuteメソッドを使用します。
構文:Execute(string)
Executeメソッドは引数stringに指定した文字列を検索し、検索結果をMatchオブジェクトを含むMatchesコレクションとして返します。
アルファベットから始まり数字も含み「.com」で終わる文字列を正規表現パターンで指定し、複数マッチを有効にするため.Global = TrueとしてExecuteメソッドで検索を行っています。
↓サンプルコード13~19行↓
見つかった場合、MatchesコレクションのCountプロパティで見つけた数だけ処理を繰り返します。
With Mc
If .Count > 0 Then
For i = 0 To .Count – 1
Itemプロパティは指定したIndex番号のMatchオブジェクトを返します。このMatchオブジェクトが実際に検索された文字列なのでValueプロパティで文字列を取得し変数msgに代入します。
ちなみにItemプロパティのIndex番号は「0」から始まります。
msg = msg & i + 1 & “番目の文字列:” & _
.Item(i).Value & vbLf
後は検索して取得した文字列をメッセージボックスで表示します。
If msg = “該当なし” Then
MsgBox msg, vbCritical
Else
MsgBox msg, vbInformation
End If
少々わかりにくい部分もあるかと思います。RegExpオブジェクトやMatchオブジェクト、Matchesコレクションなどについては、こちらのMSDNにもありますので、ご参考までに。
3.正規表現の利用と文字列置換
文字列置換のサンプルについても同様にセルA1に書込まれた文字列に対して処理を行います。
画像に示す通りセルA1に「Replace Method」と文字が入力されていますので、「R」で始まり「e」で終わる文字列を検索して「リプレイス」に置換します。
実行結果は以下になります。
◆サンプルコード(Sample3:Replaceメソッド)
Sub Sample3() '正規表現を使用して文字列を置換 '**Replaceメソッド** Dim Re As Object '正規表現を利用する為のRegExpオブジェクトを作成 Set Re = CreateObject("VBScript.RegExp") With Re '正規表現パターンを設定 '「R」で始まり「e」で終わる文字列を '「リプレイス」に置換する .Pattern = "[R][A-Z,a-z]+[e]" MsgBox .Replace((Cells(1, 1).Value), "リプレイス"), _ vbInformation End With End Sub
このように文字列を置換する場合はReplaceメソッドを使用します。
構文:Replace(String1,String2)
Replaceメソッドは引数string1に指定した値を検索し、引数string2に指定した文字列を置換するものです。
サンプルでは検索する文字列を正規表現パターンで設定しますので、「R」で始まり「e」で終わる文字列を.Pattern = “[R][A-Z,a-z]+[e]”としています。
後はメッセージボックスで表示する際にReplaceメソッドを使用して文字列置換を行っています。
MsgBox .Replace((Cells(1, 1).Value), “リプレイス”), vbInformation
4.まとめ
以上が正規表現を利用した存在チェックや検索、置換などの例になりますが、こうして実行してみると改めて正規表現の利便性がわかりますね。
文字列パターンを正しく作成することができていれば、文字列検索の柔軟性が飛躍的に向上するものと思いますので、私自身今後も意識して対応していければと思います。
以上、正規表現を使用して検索や置換を行う方法についてでした!今回の記事が何かの参考になれば幸いです。
Ryo