2016-02-06 42 views
6

我試圖用批處理腳本替換~{~}的所有實例,以便VBScript不假定我的意思是當我將它傳遞給sendKeys時敲入回車,但是,該變量一直被字面字符串代替代替它。如何在set/replace命令中轉義「〜」?

例如,

rem Intended function; 
rem input = Hello~world. 
rem output = Hello{~}world. 
每次

然而,要麼什麼也不做,或設置refVar字面字符串refVar:~={~}

這是我的嘗試;

set refVar=!refVar:~={~}! 

rem Also 
set refVar=%refVar:~={~}% 

rem and... 
set refVar=%refVar:^~=^{^~^}% 

rem and of course; 
set refVar=!refVar:^~=^{^~^}! 

rem and even: 

set "pre=~" 
set "post={~}" 
set refVar=%refVar:!pre!=!post!% 

rem and the same set commands with; 
set refVar=!refVar:%pre%=%post%! 

我錯過了一種逃避方法嗎?我很確定它與~是一個類似命令中的位置字符有關。

我知道這可能是一種解決VBScript中的問題的方法,但是這讓我困擾,沒有明顯的解決方法給我一個限制。

回答

2

我提供了一個可能更簡單的解決方案,用於替換環境變量的值字符串中的每個波浪號字符,而不是使用大於Dennis van Gils的波浪符號,該工作方式對此任務也適用。

@echo off 
set "TestVar=hello~world." 
echo TestVar has value: %TestVar% 
call :SpecialReplace "TestVar" 
echo TestVar has value: %TestVar% 
goto :EOF 


rem The subroutine below expects the name of an environment variable as 
rem parameter. The subroutine does nothing if called without parameter. 
rem Also nothing is done if specified environment variable is not defined. 

rem Each tilde character in value of this environment variable is replaced 
rem by {~} by this subroutine. 

rem Note: This subroutine can be also easily modified to replace other 
rem special characters like the equal sign by a different string which 
rem can be also no string in case of special character should be removed. 
rem Just modify Search and Replace variables for a different replace. But 
rem be aware of more code must be changed if search string is longer than 
rem one character. Length of replace string does not matter on code below. 

:SpecialReplace 
if "%~1" == "" exit /B 
setlocal EnableDelayedExpansion 
set "VarName=%~1" 
set "VarValue=!%VarName%!" 
if "!VarValue!" == "" endlocal & exit /B 
set "NewValue=" 
set "Search=~" 
set "Replace={~}" 

:ReplaceLoop 
if "!VarValue:~0,1!" == "!Search!" (
    set "NewValue=!NewValue!!Replace!" 
) else (
    set "NewValue=!NewValue!!VarValue:~0,1!" 
) 
set "VarValue=!VarValue:~1!" 
if not "!VarValue!" == "" goto ReplaceLoop 
endlocal & set "%VarName%=%NewValue%" & exit /B 

對於理解使用的命令以及它們如何工作,打開命令提示符窗口中,執行有下面的命令,並完全讀取顯示每個命令的所有幫助頁面非常謹慎。

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

而且也見回答Single line with multiple commands using Windows batch file瞭解兩行多個命令與單個號命令之間是如何工作的。


的上述變體具有延長的子程序SpecialReplace支撐現在可變搜索並通過Dennis van Gils所建議的替換指定爲第二和第三參數的字符串。

@echo off 
set "TestVar=hello~world." 
echo TestVar has value: %TestVar% 
call :SpecialReplace "TestVar" "~" "{~}" 
echo TestVar has value: %TestVar% 
goto :EOF 


rem The subroutine below expects the name of an environment variable as 
rem first parameter. The subroutine does nothing if called without parameter. 
rem Also nothing is done if specified environment variable is not defined. 

rem The second parameter must be the search string. The subroutine does 
rem nothing if there is no second parameter which can be also just one 
rem or two double quotes enclosed in double quotes. 

rem The third parameter is an optional replace string. Without a third 
rem parameter all occurrences of search string are removed from value 
rem of the specified environment variable. 

rem With just one or two double quotes in double quotes as search string 
rem no replace string can be defined because command processor does not 
rem parse the quote strings as most would expect it. But """ or """" as 
rem search string with no replace string works and results in removing 
rem all double quotes or all occurrences of two double quotes. 

:SpecialReplace 
if "%~1" == "" exit /B 
setlocal EnableDelayedExpansion 
set "VarName=%~1" 
set "VarValue=!%VarName%!" 
if "!VarValue!" == "" endlocal & exit /B 
set "NewValue=" 
set "Search=%~2" 
if "!Search!" == "" endlocal & exit /B 
set "Replace=%~3" 
set "Length=0" 

:GetLength 
if "!Search:~%Length%,1!" == "" goto ReplaceLoop 
set /A Length+=1 
goto GetLength 

:ReplaceLoop 
if "!VarValue:~0,%Length%!" == "!Search!" (
    set "NewValue=!NewValue!!Replace!" 
    set "VarValue=!VarValue:~%Length%!" 
) else (
    set "NewValue=!NewValue!!VarValue:~0,1!" 
    set "VarValue=!VarValue:~1!" 
) 
if not "!VarValue!" == "" goto ReplaceLoop 
endlocal & set "%VarName%=%NewValue%" & exit /B 
+0

這確實是一個很好的答案。使用參數進行搜索和替換字符串可能會更好,以便於使用。 –

+0

哈哈,我大部分知道批處理文件腳本命令,但我猜測幫助命令是爲其他人尋找相同的答案。無論哪種方式,謝謝,很高興知道解決方案不僅僅是我未嘗試的分隔符的特定順序。 – Bloodied

+0

@Arescet是的,我添加了使用過的命令列表以及如何獲得幫助,因爲我幾乎總是在我的批處理文件相關答案上閱讀這個答案。從你的問題來看,顯然對於我來說,你很瞭解所有這些命令。 – Mofi

4

所以我做了一些挖掘,看起來真的很難。不過,我確實發現this,解決了這個問題,讓我們以此爲代碼:

@echo off 

set "input=Hello~world." 
echo input: %input% 

call :wavereplacer "%input%" {tilde} output 
set output=%output:{tilde}={~}% 
echo output: %output% 
pause 

::your own code should be above this. 
goto :eof 

:wavereplacer String Replacer [RtnVar] 
setlocal 
rem the result of the operation will be stored here 
set "result=#%~1#" 
set "replacer=%~2" 
call :strlen0.3 result wl 
call :strlen0.3 replacer rl 

:start 

    set "part1=" 
    set "part2=" 

    rem splitting the string on two parts 
    for /f "tokens=1* delims=~" %%w in ("%result%") do (
    set "part1=%%w" 
    set "part2=%%x" 
) 

    rem calculating the count replace strings we should use 
    call :strlen0.3 part1 p1l 
    call :strlen0.3 part2 p2l 
    set /a iteration_end=wl-p1l-p2l 

    rem creating a sequence with replaced strings 
    setlocal enableDelayedExpansion 
    set "sequence=" 
    for /l %%i in (1,1,%iteration_end%) do (
    set sequence=!sequence!%replacer% 
) 
    endlocal & set "sequence=%sequence%" 

    rem adjust the string length 
    set /a wl=wl+iteration_end*(rl-1) 

    rem replacing for the current iteration 
    set result=%part1%%sequence%%part2% 
    rem if the second part is empty the task is over 
    if "%part2%" equ "" (
    set result=%result:~1,-1% 
    goto :endloop 
) 


    goto :start 

:endloop 
endlocal & if "%~3" neq "" (set %~3=%result%) else echo %result% 
exit /b 

:strlen0.3 StrVar [RtnVar] 
    setlocal EnableDelayedExpansion 
    set "s=#!%~1!" 
    set "len=0" 
    for %%A in (2187 729 243 81 27 9 3 1) do (
    set /A mod=2*%%A 
    for %%Z in (!mod!) do (
     if "!s:~%%Z,1!" neq "" (
     set /a "len+=%%Z" 
     set "s=!s:~%%Z!" 

    ) else (
     if "!s:~%%A,1!" neq "" (
      set /a "len+=%%A" 
      set "s=!s:~%%A!" 
     ) 
    ) 
    ) 
) 
    endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len% 
exit /b 

這不能代替~{~}馬上,你需要使用臨時替代,在這種情況下{tilde}

1
@ECHO Off 
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "input=hello~world" 

SET "xhead=!input:%input:*~=%=!" 
SET "output=!input:%xhead%=%xhead:~0,-1%{~}!" 

ECHO %input% --^> %output% 

GOTO :EOF 

這似乎工作提供了恰好有一個~,它不是初始或終端字符。

相關問題