2017-02-01 9 views
0

バッチスクリプトを受け入れ可能な変数として引用符を受け入れないようにしようとしています。例えば引用符を含む変数を受け入れないようにバッチスクリプトに指示します

exa"mple 

それ:だから私は基本的に関係なく、それは次のように(はい、でも、単語の内部でも1引用符を持っている場合、変数は、何であるか

:setmyvar 
set /P myvariable= 
if /i %myvariable%==<anything containing one or more "> goto bad 
goto success 

:bad 
echo Variable cannot contain quotation marks. 
pause 
goto setmyvar 

:success 
echo Success! 

それを受け入れて何か別のものを入力するように促します。

ありがとう

答えて

2

Fo llowingコードは、ユーザの入力をチェックするために使用することができます

@echo off 
setlocal EnableExtensions EnableDelayedExpansion 

:setmyvar 
set "myvariable="" 
set /P "myvariable=Please enter: " 
set "TestVar=!myvariable:"=!" 

if not defined TestVar goto setmyvar 

if not "!TestVar!" == "!myvariable!" (
    echo/ 
    echo Variable cannot contain quotation marks. 
    echo/ 
    pause 
    echo/ 
    goto setmyvar 
) 

echo Success^^! 
rem Other commands. 
endlocal 

を促す前に、環境変数myvariableは、二重引用符で定義されています。 RETURNまたはENTERの場合、環境変数myvariableは現在の値を保持します(または前に定義されていない場合でも定義されていません)。

新しい環境変数TestVarが環境変数myvariableの値で定義されていますが、すべての二重引用符が削除されています。

  1. TestVarは、すべての今、ユーザーが何か、単に二重引用符を入力していなかったようで定義されていません。

    は今、三つの可能性があります。

  2. TestVarは、myvariableとは異なります。myvariableには、1文字以上の二重引用符も含まれています。
  3. TestVarは、ユーザーが二重引用符を含まない文字列を入力したときと同じです(myvariable)。

等しくない環境変数の比較は、特に指定のない限り、二重引用符で即時環境変数の展開%myvariable%が構文エラーになりとdelayed expansionを使用することが必要です。

最初のケースでは、ユーザーに再度メッセージが表示されます。

は、後者の場合、ユーザは、引用符文字列を入力すると、ユーザが以前入力した文字列を思い出して、それを編集するUP ARROWを使用することができる、再度文字列を入力することができ要件について通知されます。

3番目のケースでは、バッチファイルの実行が続行されます。

出力するテキストの感嘆符は、残りのコードがmyvariableにアクセスするために必要に応じて遅延拡張が有効であるため、2つのキャレットでエスケープする必要があります。endlocalした後、次のコマンドラインを使用している以外の環境変数myvariableはもう存在しません:

endlocal & set "myvariable=%myvariable%" 

この行は、以前の環境でmyvariableは、このコマンドラインの解析に有効な環境でのmyvariableの現在の値を指定して、コマンドendlocalによって復元定義します。

echo/は、echo.よりも安全な方法で空白行を出力するだけです。

使用されているコマンドとその動作方法を理解するには、コマンドプロンプトウィンドウを開き、次のコマンドを実行して、コマンドごとに表示されているすべてのヘルプページをすべてよく読んでください。

  • echo /?
  • endlocal /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?

setlocalendlocalの詳細についてはthis answerとそれ以外の2つの回答を参照してください。 set "variable=value"の使用に関する説明についてはWhy is no string output with 'echo %var%' after using 'set var = text' on command line?

+0

ありがとうございました!これは束を助けた!私は、 "setlocal EnableExtensions EnableDelayedExpansion"がトップ(または少なくともエコーオフの下)にあることが必須であることに気付くまで、ちょっと苦労していました。スクリプトのどこでもこの機能をオン/オフにすることができますか? – ditheredtransparency

+0

もちろん、答えに書いたとおりです。 [MC ND](http://stackoverflow.com/users/2861476/mc-nd)によって書かれた答えでは、あなたが求めていることを実証している絶対最小コマンドブロックに遅延拡張が有効になっています。コマンド拡張もデフォルトで有効になっています(レジストリ値は変更されます)。ここでは 'set/P'が利用できません。しかし、これについては、参照されている回答の1つで詳しく説明されています。 – Mofi

2

同じアプローチの答えはMofi`s answer(引用符は変数は引用符が含まれていない、その後削除されたとき、変数の値が変化しない場合)に使用される検出を引用して参照してください。コードロジックが簡素化され、遅延拡張が有効になるのは、の場合にのみ有効になります。ユーザーが入力しない何もしない場合

@echo off 
    setlocal enableextensions disabledelayedexpansion 

:input 
    set /p "userInput=? " || (
     echo Error - Empty input not allowed 
     goto :input 
    ) 

    setlocal enabledelayedexpansion 
    if not !userInput!==!userInput:^"=! set "userInput=" 
    endlocal & if "%userInput%"=="" (
     echo Error - Invalid input - quotes not allowed 
     goto :input 
    ) 

    Echo Ok - Successful input 

は、set /pコマンドが失敗し、この失敗は、新しい入力を要求し、||条件演算子(前の1が失敗した場合、次のコマンドを実行する)によって処理されます。

特殊文字と不均衡な引用符を持つ文字列を扱うと問題が発生する可能性がありますが、拡張が遅れてしまうと、より問題のある構文解析フェーズのいくつかが実行された後で変数に値を使用できます。したがって、遅延拡張が有効になり、文字列置換操作(何も指定しないで引用符を置き換える)を使用して、変数の値を引用符なしで同じ値と照合します。一致しない場合、変数を消去します。

その後、遅延拡張は不要で無効になります。引用符を含む変数に変更(クリーン)を行わず、実行前に行が解析されると、遅延参照(!var!)ではなく、通常の変数参照(%var%)を使用して読み込み操作が行のコマンドを実行する前に変数の値を変更して、変更された値を取得することができます。変数が空の場合は引用符が含まれており、新しい値を要求する必要があります。

+0

これを指摘していただきありがとうございます! – ditheredtransparency

関連する問題