2017-02-16 64 views
1

下面這段代碼被剝離所有額外的垃圾,下到剛剛產生錯誤的代碼串,批處理文件壓延特殊字符和引號內FOR循環

)「」是在意外這次。

@echo off 
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS 
Set "regex="(Test_Health=(?!100))"" 
echo Regex is: %regex% 

FOR /L %%I IN (1,1,5) DO (
Set "to_call=call crv.exe "%%I" %regex%" 
echo About to call: !to_call! 
) 

基本上,在真正的腳本,我試圖調用一個命令行工具,它與它潛在的特殊字符,以及正則表達式一個複雜的字符串。

我想出了一個解決辦法,這是%%I的最後一個引號前加一個插入符號(^):

Set "to_call=call crv.exe "%%I^" %regex%" 

但是,這感覺就像一個黑客。我做錯了什麼,我該怎麼做才能在沒有骯髒的破解的情況下獲得理想的行爲?

+1

我並不真正理解爲什麼要設置變量到一個變量,然後使用該變量來執行對另一個命令的調用。我認爲你已經完成了複雜的代碼。 – Squashman

+0

@Squashman只是霰彈槍調試好玩的後果。嘗試在輸入循環和延遲擴展之前/之後檢查變量以及管道到文件與控制檯。它不是試圖高效,而是重新表達行爲。感謝您的輸入! –

回答

2

解決您的問題沒有破解:

  • 確保!字符。在regex變量值將被識別爲文字

    • Set "regex=(Test_Health=(?^!100))"

    • 由於setlocal enabledelayedexpansion文字!字符。 "..."必須作爲^!轉義。

    • 請注意,<name>=<value>令牌整數雙引號,以防止額外解釋值。

  • 參考變量regex延遲for循環體內:

    • 使用!regex!代替%regex%

    • 爲了使生成的命令行更強勁 - 儘管它不是在這種特殊情況下需要 - 確保regex值括在雙引號(注意%%I - 作爲一個純粹的數字 - 不需要引用):
      Set "to_call=call crv.exe %%I "!regex!""

爲了把它放在一起:

@echo off 
setlocal enabledelayedexpansion enableextensions 

Set "regex=(Test_Health=(?^!100))" 
echo Regex is: %regex% 

FOR /L %%I IN (1,1,5) DO (
    Set "to_call=call crv.exe %%I "!regex!"" 
    echo About to call: !to_call! 
) 

產量:

Regex is: (Test_Health=(?100)) 
call crv.exe 1 "(Test_Health=(?!100))" 
call crv.exe 2 "(Test_Health=(?!100))" 
call crv.exe 3 "(Test_Health=(?!100))" 
call crv.exe 4 "(Test_Health=(?!100))" 
call crv.exe 5 "(Test_Health=(?!100))" 

至於你做錯了什麼

%<name>%式的變量引用 - 除了循環變量(%%I在這種情況下) - 在迴路之前在循環體((...))內展開,即使解析,所以這樣的變量可以參考中斷這個循環。

這裏的一個最小示例演示該問題:

@echo off 
Set "regex=))" 

FOR %%I IN ("dummy") DO (
    rem !! breaks, because the up-front %regex% expansion causes a syntax error. 
    echo %regex% 
) 

延遲膨脹 - 通過在!...!包圍變量名,假設setlocal enabledelayedexpansion實際上是 - 繞過這個問題:

@echo off 
setlocal enabledelayedexpansion 
Set "regex=))" 

FOR %%I IN ("dummy") DO (
    rem OK - outputs "))" 
    echo !regex! 
) 
+1

這裏肯定是優越的答案。我非常失望,忘記了我專門要求了一個看起來不像骯髒的黑客的答案。我不會把馬庫的回答稱爲_dirty_ hack,但與此相比,是的,絕對是一個可靠的差異和巨大的崩潰。與Magoo的回答不同,你的工作實際上並不僅僅是ECHO,這意味着我的命令行工具並沒有多餘的意義,我從我的測試字符串和正則表達式中獲得了很好的結果^ _^ –

2
@ECHO OFF 
SETLOCAL 
Set "regex="(Test_Health=(?^^^^!100^^)^^)"" 
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS 
echo Regex is: %regex% 

FOR /L %%I IN (1,1,5) DO (
Set "to_call=call crv.exe "%%I" %regex%" 
echo About to call: !to_call! 
) 

GOTO :EOF 

排序取決於y我們的「理想行爲」是。不幸的是,你沒有指定。

這是一個理解cmd如何工作 - 通過替換,使用轉義字符和這發生的序列。

報告正則表達式的echo不會產生正確的結果。然而,在for內,每一對插入符號都被解釋爲單個插入符號,所以所需的脫離符號與預期的輸出所需要的一樣,大概是call crv.exe "5" "(Test_Health=(?!100))"之類...

+0

Yikes。是的,我嘗試了很多不同的逃生組合,並重新定位SETLOCAL所在的位置,但那種霰彈槍調試會在一段時間後導致瘋狂......或Stack Overflow ...或SS64!^_ ^謝謝,Magoo。看到你只是逃脫了'!'和''',可以肯定的說我不會很快嘗試過這個_specific_組合...... phew! :D –

+1

Go figure ...只要它正確回聲,現在命令行工具就會生氣過度'^',哈哈!不能全部都是... –