批处理 - 如何在延迟扩展的情况下用表达式替换感叹号?

Batch - How to replace exclamation mark with expression in if with delayed expension?

为了 我需要更改一个字符串,该字符串需要用表达式替换感叹号,以便稍后在过程中转义这些感叹号。当前的解决方案在 if 中不起作用。以下工作脚本很好地说明了这个问题:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

    SET string="World^! wasserschutzpolizei^!"

    REM REM Works quite well here!
    REM SET "return1=!string:"=""!"
    REM SET "return1=%return1:!=^^^!%"
    REM SET "return1=!return1:""="!"
    REM ECHO !return1!

    IF NOT "!string!"=="" (
        SET "return1=!string:"=""!"

        REM This line doesn't work because of the % % inside the if...
        REM Because it is one logical line.
        SET "return1=%return1:!=^^^!%"
        SET "return1=!return1:""="!"

        ECHO !return1!
    )

    EXIT /B 0
ENDLOCAL

我有一种无效的方法,它使用 CALL SET:

CALL SET "return1=%%return1:!=^^^!%%"但这行不通。

考虑到我也需要其他东西的延迟扩展。

那么,我需要如何更改代码,特别是第 SET "return1=%return1:!=^^^!%" 行,以便它在 if 中工作?

避免在批处理脚本中使用多行语句。不仅很难让它们正确,而且在开发代码时也很难调试它们。当您需要在变量替换表达式中使用变量时,延迟扩展最有用。这是您的简单代码:

@setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
@set prompt=$G

set input="World^! wasserschutzpolizei^!"

@rem Works quite well here!
@set "return1=!input:"=""!"
@set "return1=%return1:!=^^^!%"
@set "return1=!return1:""="!"
@echo %return1%

@if not "!input!"=="" call :DoIt
@echo %return1%
@exit /b 0

:DoIt
@set "return1=!input:"=""!"
@set "return1=%return1:!=^^^!%"
@set "return1=!return1:""="!"
@exit 

当简短的简单表达式不能用于 if/loop 主体时使用子例程。

如果你反过来想,而不是使用 IF NOT …(,使用 IF …,你就不会遇到这个问题,因为你不会在块中设置变量:

@ECHO OFF
SET "string=World! wasserschutzpolizei!"

IF "%string%"=="" EXIT /B 1

SET "return1=%string:"=""%"
SET "return1=%return1:!=^^^!%"
SET "return1=%return1:""="%"
ECHO %return1%

PAUSE
EXIT /B 0

该字符串现在将具有预转义的感叹号,供您稍后处理。

就像 Compo 的答案一样,但是这个也适用于多个 return 变量。

IF defined string (
  SET "return1=!string:"=""!"
)
IF defined string (
    SET "return1=%return1:!=^^^!%"
    SET "return1=!return1:""="!"
)

它将代码分成两个单独的块,因此百分比扩展将起作用