我需要连接两个字符串变量并将结果放回第一个变量中。这两个字符串可以包含任意任意字符,如换行符,感叹号等。
主脚本以延迟扩展禁用运行,因此我必须使用 SETLOCAL EnableDelayedExpansion 进行实际连接。我只是不知道如何从本地和全局变量中取回结果。
我想避免使用临时文件。
我希望批处理文件允许在本地块之外延迟扩展。
感谢。
编辑:
@Jeb
我尝试使用你的代码内联,而不是在函数中,它起作用了。
然后我尝试将它放入FOR循环中,这就破坏了它
来自循环的函数调用=工作
内联是一个循环=没有为我工作。
我现在不需要这个功能。这只是一个观察结果
感谢。
@echo off
REM Changed from function call to inline implementation
setlocal EnableDelayedExpansion
cls
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^
rem TWO Empty lines are neccessary
set "original=zero*? %%~A%%~B%%~C%%~L!LF!one&line!LF!two with exclam^! !LF!three with "quotes^&"&"!LF!four with ^^^^ ^| ^< ^> ( ) ^& ^^^! ^"!LF!xxxxxwith CR!CR!five !LF!six with ^"^"Q ^"^"L still six "
setlocal DisableDelayedExpansion
SET result=""
REM call :lfTest result original
::::::::::::::::::::
for /L %%i in (1,1,2) do (
setlocal
set "NotDelayedFlag=!"
echo(
if defined NotDelayedFlag (echo lfTest was called with Delayed Expansion DISABLED) else echo lfTest was called with Delayed Expansion ENABLED
setlocal EnableDelayedExpansion
set "var=!original!"
rem echo the input is:
rem echo !var!
echo(
rem ** Prepare for return
set "var=!var:%%=%%~2!"
set "var=!var:"=%%~3!"
for %%a in ("!LF!") do set "var=!var:%%~a=%%~L!"
for %%a in ("!CR!") do set "var=!var:%%~a=%%~4!"
rem ** It is neccessary to use two IF's, else the %var% expansion doesn't work as expected
if not defined NotDelayedFlag set "var=!var:^=^^^^!"
if not defined NotDelayedFlag set "var=%var:!=^^^!%" !
set "replace=%% """ !CR!!CR!"
for %%L in ("!LF!") do (
for /F "tokens=1,2,3" %%2 in ("!replace!") DO (
ENDLOCAL
ENDLOCAL
set "result=%var%" !
@echo off
)
)
)
::::::::::::::::::::
setlocal EnableDelayedExpansion
echo The result with disabled delayed expansion is:
if !original! == !result! (echo OK) ELSE echo !result!
echo ------------------
echo !original!
pause
goto :eof
答案 0 :(得分:2)
就像我在你的另一个问题中所说:Batch: Returning a value from a SETLOCAL EnableDelayedExpansion
只需点击链接即可获得“完美”解决方案
或者我可以在此处粘贴代码
rem ** Preparing CR and LF for later use
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^
rem TWO Empty lines are neccessary
然后在功能开始时,检测delayedExpansion是OFF还是ON
setlocal
set "NotDelayedFlag=!"
setlocal EnableDelayedExpansion
在函数结束时,返回值
rem ** Prepare for return
set "var=!var:%%=%%~2!"
set "var=!var:"=%%~3!"
for %%a in ("!LF!") do set "var=!var:%%~a=%%~L!"
for %%a in ("!CR!") do set "var=!var:%%~a=%%~4!"
rem ** It is neccessary to use two IF's, else the %var% expansion doesn't work as expected
if not defined NotDelayedFlag set "var=!var:^=^^^^!"
if not defined NotDelayedFlag set "var=%var:!=^^^!%" !
set "replace=%% """ !CR!!CR!"
for %%L in ("!LF!") do (
for /F "tokens=1,2,3" %%2 in ("!replace!") DO (
ENDLOCAL
ENDLOCAL
set "%~1=%var%" !
@echo off
goto :eof
)
)
编辑:变化稍微短一点
好吧,这看起来有点复杂,在很多情况下,它可以用另一个技巧解决
如果您知道,您将从EnableDelayed切换回DisableDelayed,并且您确定不使用任何LF,那么FOR-RETURN也会起作用。
@echo off
setlocal
call :myTest result
set result
goto :eof
:myTest
setlocal EnableDelayedExpansion
rem ... do something here
set "value=^!_&_%%_|_>"
echo --
for /f ^"eol^=^
^ delims^=^" %%a in ("!value!") do (
endlocal
set "%~1=%%a"
goto :eof
)
分割for /f ^"eol^=^....
仅用于禁用eol字符。