5

のデータを変数として取得するバッチファイルで作業していますが、その変数には感嘆符が付いています。

私がやろうとしているのは、必要なエスケープ文字を変数に追加することです。

"Title":"Turk 182!"

上記は私が扱っているデータの例です。

setlocal EnableDelayedExpansion
rem replace ! with ^^!
set var=%var:!=^^!!%

しかし、それが正しい構文であるかどうかはわかりません。検索と置換の一部としても使用されている場合、エスクラメーションマークをエスケープするにはどうすればよいですか?

すべてのエスクラメーションマークをエスケープバージョンに置き換えて、表示および操作できるようにしようとしています。

ところで、すべての特殊文字を削除してエスケープできる既存の関数はバッチでありますか?

これが私がしていることを説明するのに役立つかもしれないより多くのコードです。

{"Title":"Turk 182!","Year":"1985","Rated":"PG-13","Released":"15 Feb 1985","Runtime":"1 h 42 min","Genre":"Action, Comedy, Drama","Director":"Bob Clark","Writer":"Denis Hamill, James Gregory Kingston","Actors":"Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp","Plot":"Jimmy Lynch is angry because his older brother, who was injured as a result of an off duty fire rescue...","Poster":"http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl5BanBnXkFtZTcwNjYwNjgyMQ@@._V1_SX300.jpg","imdbRating":"5.7","imdbVotes":"2,360","imdbID":"tt0090217","Response":"True"}

rem removes starting and ending brackets
set json=%json:~1,-1%
setlocal EnableDelayedExpansion
rem replace "," with linebreak
set json=!json:","="#"!
setlocal EnableDelayedExpansion
rem replace ! with ^^!
set json=%json:!=^^!!%

setlocal DisableDelayedExpansion
echo %json%
echo.
exit /b

次に、json変数をループに配置すると、真の値の代わりにエラーが発生します。上記で使用した実際の置換コマンドが表示されます。

4

4 に答える 4

6

遅延拡張を有効にしている場合は、特殊文字でパーセント拡張を使用しないでください。
代わりに遅延拡張を使用している場合は、感嘆符やその他の文字で問題が発生することはありません。

set myTitle="Turk 182!"
setlocal EnableDelayedExpansion
echo Title=!myTitle!

感嘆符を置き換えることもできますが、複数のキャレットが必要であり、その数は多くのことに依存します。

  • 感嘆符は引用符の中にありますか?
  • 直接エコーしますか、それともある変数から別の変数にコピーしてエコーしますか?
  • 別の値と比較する方法。

小さなサンプルとして、パーセント拡張が最良の選択ではない理由

@echo off
set test1=An exclamation mark^^^^!
setlocal EnableDelayedExpansion
set test2=An exclamation mark^^^^^^^^^^!
set "test3=An exclamation mark^^^^^!"
set test4a=An exclamation mark^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^!
set test4b=%test4a%!
echo %test1%
echo %test2%
echo %test3%
echo %test4b%

安全な方法でファイルからテキストを読みたい場合は、遅延トグル技術を使用できます。

setlocal DisableDelayedExpansion
for /F "delims=" %%a in (myFile.txt) DO (
  set "line=%%a"
  setlocal EnableDelayedExpansion
  echo !line!
  endlocal
)
于 2012-11-13T06:21:02.137 に答える
6

私はあなたが本当に逃げる必要があるとは確信していません!。それは可能ですが、jebが説明しようとしたように、複雑になる可能性があります。

あなたが提供したコードに基づいて、あなたは遅延拡張が何をするのか理解していないように私には見えます。HELP SETコマンドプロンプトから入力して、ドキュメントを読むことをお勧めします。遅延拡張の説明は、「最後に、遅延環境変数拡張のサポート...」という行の約半分から始まります。

拡張を遅らせることには他にも大きな利点があります。最大の利点の1つは、遅延拡張を使用するときに特殊文字をエスケープすることを心配する必要がないことです。通常の拡張を使用しながらキャラクターをエスケープするのは苦痛であり、経験を積むまでは非常に混乱する可能性があります。(それは本当に論理的で予測可能ですが、あなたがそれを理解するまで、それはぎこちないように見えます)

遅延拡張の最大の問題は、データにが含まれている場合、FORループでうまく機能しないことです!。これは、FOR変数が展開された後に拡張の遅延が発生するため、を含む値!が破損するためです。以下のjsonパーサーでは、この問題を回避するために、ループ内で遅延拡張をオフに切り替えています。

私はjsonについてあまり知らないので、以下の私の解決策は素朴(不完全)かもしれません。しかし、ここにあなたが提供したデータで動作する単純なjsonパーサーがあります。「test.txt」という名前のファイルにあなたのjson文字列を入れました

@echo off
setlocal disableDelayedExpansion
setlocal enableDelayedExpansion

::Read the json string from a file
<test.txt set /p "json="

::Define LF variable to contain a linefeed
set LF=^


::The above 2 blank lines are critical - DO NOT REMOVE

::Strip the enclosing braces
set "json=!json:~1,-1!"

::Substitute a linefeed for ","
for %%A in ("!LF!") do set "json=!json:","=%%~A!"

::Substitute = for ":"
set "json=!json:":"==!"

::Remove remaining "
set "json=!json:"=!"

::Loop through the data, creating variables of the form var_name=value
for /f "delims=" %%A in ("!json!") do (

  REM If delayed expansion is enabled then endlocal to get back to disabled state
  if "!!" equ "" endlocal

  REM Create the variable
  set "var_%%A"
)

::Display the results - list all variables that begin with var_
set var_

これが出力です

var_Actors=Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp
var_Director=Bob Clark
var_Genre=Action, Comedy, Drama
var_imdbID=tt0090217
var_imdbRating=5.7
var_imdbVotes=2,360
var_Plot=Jimmy Lynch is angry because his older brother, who was injured as a result of an off duty fire rescue...
var_Poster=http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl5BanBnXkFtZTcwNjYwNjgyMQ@@._V1_SX300.jpg
var_Rated=PG-13
var_Released=15 Feb 1985
var_Response=True
var_Runtime=1 h 42 min
var_Title=Turk 182!
var_Writer=Denis Hamill, James Gregory Kingston
var_Year=1985
于 2012-11-13T12:40:35.633 に答える
1

PowerShellを使用できます。

$json=@"
  {"Title":"Turk 182!","Year":"1985","Rated":"PG-13","Released":"15 Feb 1985","Runtime":"1 h 42 min","Genre":"Action, Comedy, Drama","Director":"Bob Clark","Writer":"Denis Hamill, James Gregory Kingston","Actors":"Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp","Plot":"Jimmy Lynch is angry because his older brother, who was injured as a result of an off duty fire rescue...","Poster":"http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl5BanBnXkFtZTcwNjYwNjgyMQ@@._V1_SX300.jpg","imdbRating":"5.7","imdbVotes":"2,360","imdbID":"tt0090217","Response":"True"}
"@

add-type -assembly system.web.extensions
$jserial = new-Object Web.Script.Serialization.JavaScriptSerializer
$jserial.DeserializeObject($json)

Key                                                         Value
---                                                         -----
Title                                                       Turk 182!
Year                                                        1985
Rated                                                       PG-13
Released                                                    15 Feb 1985
Runtime                                                     1 h 42 min
Genre                                                       Action, Comedy, Drama
Director                                                    Bob Clark
Writer                                                      Denis Hamill, James Gregory Kingston
Actors                                                      Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp
Plot                                                        Jimmy Lynch is angry because his older brother, who was ..
Poster                                                      http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl..
imdbRating                                                  5.7
imdbVotes                                                   2,360
imdbID                                                      tt0090217
Response                                                    True

またはPowerShellv3の場合:

PS III> $json | ConvertFrom-JSON

Key                                                         Value
---                                                         -----
Title                                                       Turk 182!
Year                                                        1985
Rated                                                       PG-13
Released                                                    15 Feb 1985
Runtime                                                     1 h 42 min
Genre                                                       Action, Comedy, Drama
Director                                                    Bob Clark
Writer                                                      Denis Hamill, James Gregory Kingston
Actors                                                      Timothy Hutton, Robert Urich, Kim Cattrall, Robert Culp
Plot                                                        Jimmy Lynch is angry because his older brother, who was ..
Poster                                                      http://ia.media-imdb.com/images/M/MV5BMTQ2OTk1ODA1MV5BMl..
imdbRating                                                  5.7
imdbVotes                                                   2,360
imdbID                                                      tt0090217
Response 
于 2012-11-13T16:36:18.447 に答える
1

jebとdbenhamはすでに質問に完全に答えているので、これはややトピックから外れています...

さまざまな状況で感嘆符を使用するために挿入する必要のあるキャレットの数を覚える手間を省くために、小さなトリックを使用しました。Delayed Expansionを無効にして変数を定義し、それに感嘆符を割り当てます(私はそれをbangと呼びました)。次に、遅延拡張を有効にして、!bang!として使用します。このように、この値は常に感嘆符として表示され、非常に簡単に記述できます...

@echo off
setlocal DisableDelayedExpansion
set bang=!
setlocal EnableDelayedExpansion
echo Yes, it works!bang!

アントニオ

于 2012-11-13T20:25:06.627 に答える