Batch file Replace the exclamation mark with a shielded exclamation mark

I am working on a batch file that receives data as a variable, and in this variable has an exclamation mark.

What I'm trying to do is add the necessary escape characters to the variable.

"Title":"Turk 182!" 

The above is an example of the data I'm working with.

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

But I'm not sure if this is the correct syntax, so how can I avoid the esclamation label if it is also used as part of the search and replace?

I am trying to replace all esclamation tags with a shielded version so that it can display and work with it.

Btw, are there any existing functions in the package that will remove and allow escaping of all special characters?

Here is some more code that can help explain what I'm doing.

 {"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 

Then I put the json variable in a loop, and it throws an error instead of the true value. I just see the actual replacement command above.

+5
source share
4 answers

I'm not sure you really need to run ! . This can be done, but, as Jay tried to explain, it can get complicated.

Based on the code you provided, it seems to me that you do not understand what a slow extension is. I suggest you type HELP SET from the command line and read the documentation. The description of delayed expansion begins about halfway down with a line that reads: "Finally, support for delayed change of environment variables ..."

There are other important benefits to delaying expansion. One of the biggest advantages is that you never have to worry about avoiding special characters when you use a delayed extension. Escaping characters using normal expansion is a pain, and can be very confusing until you gain experience. (This is really logical and predictable, but as long as you do not understand it, it looks like gibberish)

The biggest problem with extension delay is that it does not play well with FOR loops when the data contains ! . This is because slow expansion occurs after the FOR variable expands, so values ​​containing ! will be damaged. In my json syntax below, I toggle the delayed extension in a loop to avoid this problem.

I don't know much about json, so my solution below may be naive (incomplete). But here is a simple json parser that works with the data you provided. I put your json string in a file called "test.txt"

 @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_ 

Here is the conclusion

 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 
+6
source

If you enable deferred extension, you should not use percentage extension with special characters.
If you use a deferred extension, you will not have problems with exclamation marks or other characters.

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

You can replace exclamation points, but you need several times, and the amount depends on many things.

  • An exclamation mark inside quotation marks?
  • Do you repeat this directly or want to copy from one variable to another and then repeat?
  • How to compare this with a different value.

As a small example, why percentage expansion is not the best choice

 @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% 

If you want to read text from a file in a safe way, you can use the delayed switching method.

 setlocal DisableDelayedExpansion for /F "delims=" %%a in (myFile.txt) DO ( set "line=%%a" setlocal EnableDelayedExpansion echo !line! endlocal ) 
+5
source

you can use 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 

or with PowerShell v3:

 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 
+1
source

jeb and dbenham completely answered the question, so this is a little off topic ...

I used a little trick to avoid unnecessary trouble about how much I should remove in order to use the exclamation point in various situations. I define the variable with the delay turned off and assign it an exclamation mark (I named it). Then I turn on Delayed Expansion and use it like! Bang !. Thus, this value will always be displayed as an exclamation point, and it is very easy to write ...

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

Antonio

+1
source

Source: https://habr.com/ru/post/1445688/


All Articles