電磁波に撃たれて眠りたい!

今日も電磁波浴びまくりのIT業界で働く@mamohacyがガジェット/クラウド/IT業界を語ってくブログ

VBAで文字列がURLとして正しいかどうかを正規表現を使って判断する方法

個人的にハマったのでメモ。 まず、VBAで正規表現を使うには、RegExpオブジェクトが使えるのですが、この辺りはいろいろな文献があるので下記を参考にされたし。

↓VBAで正規表現を使う(1/3):CodeZine
http://codezine.jp/article/detail/1655

ひとことで言えば、参照設定の変更で「Microsoft VBScript Regular Expressions 5.5」を追加してやればよろしい。 とりあえず、URLとして正しい表記は下記のRFC1738(http://www.faqs.org/rfcs/rfc1738.html)に記載されているので言及しないけど、先頭のURLスキーム以降の文字としていったい何が認められているのか?が問題でしょう。 半角英数字はもちろんOKだとして、記号については下記の文字列が認められています。

「-」 ⇒ ハイフン
「_」 ⇒ アンダースコア
「!」 ⇒ エクスクラメーション
「~」 ⇒ チルダ
「'」 ⇒ シングルクォート
「;」 ⇒ セミコロン
「:」 ⇒ コロン
「@」 ⇒ アットマーク
「&」 ⇒ アンパサンド
「=」 ⇒ イコール
「,」 ⇒ カンマ
「%」 ⇒ パーセント
「#」 ⇒ スクエア(パウンド)
「/」 ⇒ スラッシュ
「$」 ⇒ ダラー
「*」 ⇒ アスタリスク
「+」 ⇒ プラス
「?」 ⇒ クエスチョン
「.」 ⇒ ピリオド
「(」 ⇒ 左括弧
「)」 ⇒ 右括弧

 

さらに、RegExpオブジェクトのPatternに指定できる文字列として、下記のものについては別の意味が充てられているため、「\」でエスケープして使用する必要があります。

「$」 ⇒ 末尾に一致
「*」 ⇒ 直前の文字と0回以上一致
「+」 ⇒ 直前の文字と1回以上一致
「?」 ⇒ 直前の文字と0回または1回一致
「.」 ⇒ 改行文字以外の文字と一致
「(」 ⇒ ()内に指定した文字と一致
「)」 ⇒ ()内に指定した文字と一致

 

※他にもあるけど割愛するよ! ということで、これを正規表現で表してみると

 [-_!~';:@&=,%#/a-zA-Z0-9\$\*\+\?\.\(\)]+

になります。意味は[]内に記載された文字が1回以上繰り返されていること、です。 で、先頭のURLスキームにはいろいろあるのですが、とりあえずhttpとhttpsとftpだけを考慮すると、

 ^(http|https|ftp)

になります。「^」は文字列の先頭という意味で、()内の「|」で区切られた文字列のいずれかが、 文字列の先頭に来ていること、という意味になります。 これをもっと短く書き換えると、

 ^(https*|ftp)

となります。「*」は「直前の文字の0回以上の繰り返し」なので、「s」があってもなくてもOK、という意味 です。 これまでの文字列を全部組み合わせて、RegExpのPatternにセットする文字列としては、

 ^(https*|ftp)://[-_!~';:@&=,%#/a-zA-Z0-9\$\*\+\?\.\(\)]+$

になります。最後の「$」は末尾に一致という意味で、これをつけておかないと文字列の 途中までが正しいURL表記であったものもマッチしてしまうので必ず付ける必要があります。 イカソース!

Private Sub Main()
   Dim objRE As RegExp
   Dim strPtn As String
   Dim strURL1 As String
   Dim strURL2 As String
   Dim strURL3 As String

   '正規表現のパターン
   strPtn = "^(https*|ftp)://[-_!~';:@&=,%#/a-zA-Z0-9\$\*\+\?\.\(\)]+$"

   'スキームが間違ってる
   strURL1 = "httttp://www.hogehoge.com/"
   '使っちゃダメな文字が入ってる
   strURL2 = "http://www.hogehoge.com/damedesu[yo!.html"
   '正しいやつ
   strURL3 = "http://www.hogehoge.com/docs/index.php?inp=1234&del=abcd"

   Set objRE = New RegExp
   objRE.Pattern = strPtn

   Debug.Print "「" & strURL1 & "」のチェック結果:" & objRE.Test(strURL1)
   Debug.Print "「" & strURL2 & "」のチェック結果:" & objRE.Test(strURL2)
   Debug.Print "「" & strURL3 & "」のチェック結果:" & objRE.Test(strURL3)
End sub

イミディエイトウィンドウに表示される実行結果

「httttp://www.hogehoge.com/」のチェック結果:False
「http://www.hogehoge.com/damedesu[yo!.html」のチェック結果:False
「http://www.hogehoge.com/docs/」のチェック結果:True