読者です 読者をやめる 読者になる 読者になる

やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

正規表現を使ってディレクトリ名をバリデートしてみた

前回のつづき。リポジトリ名のエラーチェックをしてみた。

入手先

GitHub Yahoo

開発環境

使い方

  1. リポジトリ名にしたいディレクトリを用意する
  2. コード一式をそのディレクトリ配下に配置する
  3. CallVBScript.batファイルをダブルクリックで実行する

ディレクトリ名がC++Dirなど不正値ならエラーが出る。 Dialog Console

半角英数字と.,-,_の文字だけなら成功。 ダイアログは表示しない。

Console

調査ログ

GitHubのReadMeだけ見ればいい。

以下は読む必要なし。いろいろ大変だったログ。

バッチファイルで正規表現…はできなかった

http://oshiete.goo.ne.jp/qa/8335749.html

どうやらWindowsのコンソールcmd.exeでは、findstrコマンドを使うらしい。 でも、対象文字列をファイルから取得することしかできないっぽい。 コンソールの標準出力を対象にしたいのだが。

どうやらbat(cmd.exe)では、標準出力の文字列を正規表現チェックすることはできないらしい。

CScriptなら正規表現を扱える

http://kunst1080.hatenablog.com/entry/2013/06/23/235300

代わりにCScript(WScript)を使う。これもcmd.exe同様Windows限定。

https://msdn.microsoft.com/ja-jp/library/cc427970.aspx JScriptVBScriptにおける正規表現の定義の仕方。違いがあるらしい。

リポジトリ名のチェックはCScript(vbs,js)でやろう。

batからvbsを呼び出す

http://tsg21.com/vbs4bat.html

set script_file=check.vbs
::set script_file=check.js
set script_param=
>call cscript //NoLogo "%script_file%" "%script_param%"

vbsからbatへ戻り値を返せない

ところで、戻り値は?見つけられなかった。

.batから.js(.vbs)を呼び出して、.batへ値を返したい。でも多分できない。

以下のような方法はあるらしいが、苦肉の策。 http://piyopiyocs.blog115.fc2.com/blog-entry-892.html http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q13151834463

スクリプト環境間でのやりとりは面倒すぎる

言語 戻り値
.sh 0~255(8bit値)
.bat たぶんshと同様。
cscript,wscript (.vbs,.js) 見つけられなかった
  • 戻り値をやりとりする方法
    • 環境変数を設定する(.bat, .sh)
      • 異なるファイル間の場合も使えるのか。スコープが不明
    • 一時ファイル
      • ファイル書込、読取が必要。絶対嫌。

.sh, .batは環境変数を通じて渡すのが無難か。 ファイルをまたいだ環境変数のスコープについて調査する必要がありそう。 cscript(.vbs,.js)との連携は難しいか。 実行環境や言語が異なると、その連携で悩まされる。

方針

楽をするため、bat,sh,vbsの各スクリプト環境間での連携は考えないようにする。

VBS(JScript)で親ディレクトリ名が ^[0-9a-zA-Z._-]+$ のパターンに一致しているか確認しよう。 エラーならエラーダイアログを出せばいい。 もしエラーでないなら、JScript側から.batを呼び出せばいい。

気に食わない

しかし、Startするバッチが変わってしまう。 正規表現を使いたいため"だけ"にCScript(vbs,js)を使うのが気に食わない。 さらに、その制約のせいで開始バッチまで変わってしまう。

嫌だけど妥協するか。

頼れぬ.NET Framework

もしくはPowerShellを検討してみるか。

たかが正規表現のためだけに.NET Frameworkに依存するのが気に食わない。 curlの代わりになることができるならいいが、.NET 4.0のHttpRequestではGitHubと通信できなかった。

MSDN

https://msdn.microsoft.com/ja-jp/library/cc392403.aspx

Matchesのメンバについて説明がない。countがあるのかないのか。 http://www2s.biglobe.ne.jp/iryo/vba/part5/vbs2.html "Count"プロパティがあるらしい。

リファレンスなどの資料がしょぼい。 MSDNより個人サイトのほうで見つけたものもあった。

VBSは外部ファイルから呼び出せない

なんと、VBSは外部ファイルから呼び出せないらしい。 http://qiita.com/honeniq/items/88462b12d2244480026a VBSにはbatにおけるcallやstartに該当するものすらない。 関数をライブラリ化したかったのにできない。

かさばるコード

' ------------------
' 正規表現に一致するか
' ------------------
Function IsMutchRegExp(pattern, target)
    Dim reg, Match, Matches, RetStr
    Set reg = new RegExp
    reg.Pattern = pattern
    reg.IgnoreCase = False
    reg.Global = True
    Set Matches = reg.Execute(target)
    If Matches.Count = 1 Then
        IsMutchRegExp = True
    Else
        IsMutchRegExp = False
    End If
End Function


' 親フォルダの名前を取得する
Dim fsobj, DirectoryName
Set fsobj = CreateObject("Scripting.FileSystemObject")
DirectoryName = fsobj.GetFolder(fsobj.GetParentFolderName(WScript.ScriptFullName)).Name

この程度の仕事をするのに、自前でこれだけコーディングが必要だった。 しかも本番はまだ。こいつらを利用して条件分岐やらが必要。

構文や記述もやたらと野暮ったくて面倒くさい。

まったく捗らない

実行環境に振り回される

たかがWebAPIで自動化したいだけなのに、.sh, .bat, .vbsの言語をさわる羽目になった。

文字コード問題(CP932/UTF8)、ファイルシステム間問題(区切文字などパス関係)、など、言語以前の問題に悩まされる。

さらに各言語の構文を知らねばならない。 変数の宣言や定義や使い方だけでも細かな違いがあって大変だった。

言語間、ファイル間で引数として簡単にやりとりできればよかったのだが、簡単にはできない。 文字コード問題、ファイルシステム間問題、そもそもインクルードできないなど。

おかげで、「親ディレクトリ名を取得する」ということを3言語で調査する羽目になった。 本当は、どこか1つだけで取得して、あとはパラメータとして渡したかった。 そうすれば私の学習も少しで済んだし、バッチ処理で同じことを何回もやらずに済む。

.bat

for %%I in (.) do set REPOSITORY_NAME=%%~nI%%~xI

.sh

REPO_NAME=`dirname "$0"`
REPO_NAME=`basename ${REPO_NAME}`

.vba

Dim fsobj, DirectoryName
Set fsobj = CreateObject("Scripting.FileSystemObject")
DirectoryName = fsobj.GetFolder(fsobj.GetParentFolderName(WScript.ScriptFullName)).Name

.shが最も分かりやすい。.bat, .vbaはどちらも分かりにくい。

もっと楽な方法はないのか

VBSを触った印象は最悪。 もはや問題をリストアップすることすら馬鹿馬鹿しいほど。 できれば二度と触りたくない。

こんなことならPythonRubyのほうがまだ楽だったに違いない。 触ったことないけど。

いまさらだが、PythonRubyならcurl的なことができるかもしれない。 そうすれば全部その言語だけで完結できる。 http://qiita.com/wappy100/items/4ee5ffa86e3cb9a3d970 http://techhey.hatenablog.com/entry/2014/01/24/015147

C#でできたら一番良かったのに…。 以前試したらできなかった。

WindowsXPという古い環境で、GitHub通信プロトコルのバージョンが古いのが原因だった。 PythonRubyでも同じ問題にぶちあたるかもしれない。 XPでは古いのしか使えないから。

所感

たかがディレクトリ名のバリデートごときでこれほど苦労するとは思わなかった。

きっともっと楽な方法はあるはず。