正規表現で迷走中です。
テキストから社員番号を取り出したい!をやってみたいと思います。
正規表現のパターンの指定の仕方などは末尾に参考記事を載せていますので、そちらにてご確認ください。
1.社員番号を取り出したい!
以下のテキストから社員番号を取り出そうとしています。社員番号は文字列の中で「社員番号XXXXXX」と社員番号につづいて数字で示された部分が社員番号です。社員番号は6桁の場合と7桁の場合があります。
パターンは 社員番号\d{6,7} で指定します。
\d は数字を表します。\d{6,7}で数字6~7文字の繰り返し、ということを表します。
社員番号\d{6,7} で、社員番号という文字列に続いて数字6~7文字の文字列がパターンに一致する、ということになります。
たとえば 「社員番号1234567」 「社員番号123456」ですね。
「社員番号が1234567」はパターンに当てはまりません。社員番号と数字の間に「が」が入っているからです。
「社員番号123」も当てはまりません。数字が3桁だからです。
以下のコードでやってみます。
Sub 社員番号取り出し1()
Dim re As RegExp '正規表現クラスオブジェクト
Set re = New RegExp
re.Global = True '検索範囲(True:文字列の最後まで検索)
re.IgnoreCase = True '大文字小文字の区別(True:区別しない)
re.Pattern = "社員番号\d{6,7}" '検索パターン"
'検索結果を受け取るMatchesコレクション
Dim Matches As MatchCollection
'検索実行
'A列の文字列を検査し、結果をB列以降に出力
Dim i As Long
i = 2
Do Until Cells(i, 1).Value = ""
If re.test(Cells(i, 1).Value) = True Then
Set Matches = re.Execute(Cells(i, 1).Value)
Cells(i, 2).Value = Matches(0)
End If
i = i + 1
Loop
End Sub
結果はこうなりました。
If re.test(Cells(i, 1).Value) = True Then
としているのは、合致しない場合、出力する Cells(i, 2).Value = Matches(0) のところでMatchesがないためエラーになってしまうのを避けるためです。
途中で止めてローカルで見てみた様子です。
Matchesのitemの中のValueにパターンに合致した文字列が格納されています。
Matches(0)でItem1の中身が取り出せます。
ちなみに複数合致した場合はItem2,Item3・・・に入っていきます。
Matches(1)、Matches(2)・・・で取り出すことができます。
通常はそのような書き方はせず、 For each match In Mathes で取り出していきます。
2.社員番号の数字の部分だけ取り出したい!
パターンをこのように指定します。
re.Pattern = “社員番号(\d{6,7})”
取り出したい部分を () で囲みます。
コードはこちら
Sub 社員番号取り出し2()
Dim re As RegExp '正規表現クラスオブジェクト
Set re = New RegExp
re.Global = True '検索範囲(True:文字列の最後まで検索)
re.IgnoreCase = True '大文字小文字の区別(True:区別しない)
re.Pattern = "社員番号(\d{6,7})" '検索パターン"
'検索結果を受け取るMatchesコレクション
Dim Matches As MatchCollection
'検索実行
'A列の文字列を検査し、結果をB列以降に出力
Dim i As Long
i = 2
Do Until Cells(i, 1).Value = ""
If re.test(Cells(i, 1).Value) = True Then
Set Matches = re.Execute(Cells(i, 1).Value)
Cells(i, 2).Value = Matches(0).SubMatches(0)
End If
i = i + 1
Loop
End Sub
変更したところは2か所。
検索パターン
re.Pattern = “社員番号(\d{6,7})”
出力する箇所で SubMatches(0)としているところです
ells(i, 2).Value = Matches(0).SubMatches(0)
結果はこちら
3.複数のマッチした部分を取り出したい!
ちょっと趣向を変えて、テキスト「社員番号0123456、社員番号1234567、社員番号9876543」から社員番号を取り出してみたいと思います。
コードはこちら
Sub 社員番号取り出し3()
Dim re As RegExp '正規表現クラスオブジェクト
Set re = New RegExp
re.Global = True '検索範囲(True:文字列の最後まで検索)
re.IgnoreCase = True '大文字小文字の区別(True:区別しない)
re.Pattern = "社員番号(\d{6,7})" '検索パターン"
'検索結果を受け取るMatchesコレクション
Dim Matches As MatchCollection
'MatchesCollectionを受け取るMatchオブジェクト
Dim match As match
'検索実行
Dim buf As String
buf = "社員番号0123456、社員番号1234567、社員番号9876543"
Set Matches = re.Execute(buf)
Dim i As Long: i = 2
For Each match In Matches
Cells(i, 1).Value = match.SubMatches(0)
i = i + 1
Next match
End Sub
結果はこちら。ちなみにA列は書式設定で「文字列」としています。
途中で止めてローカルでMatchesコレクションの中身を見てみたところ
Matchesコレクションの中に複数のアイテムがあるから、ForEachでひとつずつアイテムを取り出して、SubMatchesを処理していく、というイメージですね。
4.正規表現の記事(内部リンク)
ほかにも正規表現記事あります(内部リンク)よろしければどうぞ。
【Excel/VBA】VBAで正規表現~郵便番号でやってみる
【Excel/VBA】VBAで正規表現~マッチした文字列の取り出し
5.参考文献・記事
参考とさせていただいた記事です。ありがとうございました!
正規表現とは?メタ文字とサンプル一覧
https://www-creators.com/archives/4278
正規表現:文字列を「含まない」否定の表現まとめ
https://www-creators.com/archives/1827
コメント