如何反转批处理文件中的字符串
how to reverse strings in a batch file
我有三个字符串 t1=3
、t2=1
和 t3=5
。
想要反转这些字符串,以便 t1=5
、t2=1
和 t3=3
。
它们一起形成一个数字(输入:315 和 output:513)。
我需要反转它们形成的数字。
我试过这样做:
set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"
当我尝试它时,它从它们形成的数字中删除了 t1
(输入:315 和输出:13)。
我不知道为什么会这样。
我猜你的 set
命令都在带括号的代码块中(例如 for
循环),你没有在应该的时候使用延迟扩展。如果是这种情况,您可能可以通过这种方式修复现有代码:
setlocal enabledelayedexpansion
set "rest2=!t1!"
set "t1=!t3!"
set "t3=!rest2!"
只是为了让我觉得我已经完成了一些事情,这里有一个实用函数可以反转可能会解决您的问题的字符串。为了缩短执行时间,这个限制为 100 个字符。我猜这对大多数情况都没有问题。
@echo off
setlocal
set /P "input=Input? "
call :reverse flipped "%input%"
echo %input% reversed is %flipped%
rem // end main runtime
goto :EOF
rem // functions
:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2"
for /L %%I in (0,1,100) do (
if "!str!"=="" for %%a in ("!ret!") do (
endlocal & set "%~1=%%~a" & exit /b
)
set "ret=!str:~0,1!!ret!"
set "str=!str:~1!"
)
如果您希望函数工作到变量可以携带的字符限制,您可以将 100 增加到 8192,但这将导致 for /L
循环循环 8192 次,无论如何是否被exit /b
1打破。没有真正优雅的方式来突破 for /L
(尽管它比 goto
循环快得多)。
在触发 for /L
循环之前添加一个函数来获取字符串的长度可以使您的代码对长字符串更有效,同时不会显着影响短字符串。虽然代码多了很多,但是比上面的脚本速度要快。
@echo off
setlocal
set /P "input=Input? "
call :reverse flipped "%input%"
echo %input% reversed is %flipped%
goto :EOF
:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2" & call :length len "%~2"
for /L %%I in (0,1,%len%) do (
if "!str!"=="" for %%a in ("!ret!") do (
endlocal & set "%~1=%%~a" & exit /b
)
set "ret=!str:~0,1!!ret!"
set "str=!str:~1!"
)
:length <return_var> <string>
setlocal enabledelayedexpansion
if "%~2"=="" (set ret=0) else set ret=1
set "tmpstr=%~2"
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if not "!tmpstr:~%%I,1!"=="" (
set /a ret += %%I
set "tmpstr=!tmpstr:~%%I!"
)
)
endlocal & set "%~1=%ret%"
exit /b 0
1 当在 for /L
循环中遇到 goto :EOF
或 exit /b
时,计数继续,尽管 [=23 之后的东西=] 被忽略。
对不起。您的代码 不可能 产生 13 作为输出。如果代码在括号内,则变量 rest2 未定义,因此删除的变量为 t3
,因此输出必须为 51。您可以在以下代码中测试这一点:
@echo off
setlocal
set t1=3
set t2=1
set t3=5
echo %t1%%t2%%t3%
(
set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"
)
echo %t1%%t2%%t3%
我建议您仔细检查您的代码,寻找其他部分的错误。
如果问题是代码在括号中,那么解决它的方法是通过延迟扩展,正如 rojo 在他的回答中所解释的那样。但是,如果括号中的代码是而不是,那么你应该知道你可以实现t1
和t3
的交换rest2
辅助变量 只要你把两个赋值放在同一行:
set "t1=%t3%" & set "t3=%t1%"
这是有效的,因为在执行结果行之前用百分比括起来的变量被它们的值替换。
我有三个字符串 t1=3
、t2=1
和 t3=5
。
想要反转这些字符串,以便 t1=5
、t2=1
和 t3=3
。
它们一起形成一个数字(输入:315 和 output:513)。
我需要反转它们形成的数字。
我试过这样做:
set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"
当我尝试它时,它从它们形成的数字中删除了 t1
(输入:315 和输出:13)。
我不知道为什么会这样。
我猜你的 set
命令都在带括号的代码块中(例如 for
循环),你没有在应该的时候使用延迟扩展。如果是这种情况,您可能可以通过这种方式修复现有代码:
setlocal enabledelayedexpansion
set "rest2=!t1!"
set "t1=!t3!"
set "t3=!rest2!"
只是为了让我觉得我已经完成了一些事情,这里有一个实用函数可以反转可能会解决您的问题的字符串。为了缩短执行时间,这个限制为 100 个字符。我猜这对大多数情况都没有问题。
@echo off
setlocal
set /P "input=Input? "
call :reverse flipped "%input%"
echo %input% reversed is %flipped%
rem // end main runtime
goto :EOF
rem // functions
:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2"
for /L %%I in (0,1,100) do (
if "!str!"=="" for %%a in ("!ret!") do (
endlocal & set "%~1=%%~a" & exit /b
)
set "ret=!str:~0,1!!ret!"
set "str=!str:~1!"
)
如果您希望函数工作到变量可以携带的字符限制,您可以将 100 增加到 8192,但这将导致 for /L
循环循环 8192 次,无论如何是否被exit /b
1打破。没有真正优雅的方式来突破 for /L
(尽管它比 goto
循环快得多)。
在触发 for /L
循环之前添加一个函数来获取字符串的长度可以使您的代码对长字符串更有效,同时不会显着影响短字符串。虽然代码多了很多,但是比上面的脚本速度要快。
@echo off
setlocal
set /P "input=Input? "
call :reverse flipped "%input%"
echo %input% reversed is %flipped%
goto :EOF
:reverse <return_var> <string>
setlocal enabledelayedexpansion
set "ret=" & set "str=%~2" & call :length len "%~2"
for /L %%I in (0,1,%len%) do (
if "!str!"=="" for %%a in ("!ret!") do (
endlocal & set "%~1=%%~a" & exit /b
)
set "ret=!str:~0,1!!ret!"
set "str=!str:~1!"
)
:length <return_var> <string>
setlocal enabledelayedexpansion
if "%~2"=="" (set ret=0) else set ret=1
set "tmpstr=%~2"
for %%I in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if not "!tmpstr:~%%I,1!"=="" (
set /a ret += %%I
set "tmpstr=!tmpstr:~%%I!"
)
)
endlocal & set "%~1=%ret%"
exit /b 0
1 当在 for /L
循环中遇到 goto :EOF
或 exit /b
时,计数继续,尽管 [=23 之后的东西=] 被忽略。
对不起。您的代码 不可能 产生 13 作为输出。如果代码在括号内,则变量 rest2 未定义,因此删除的变量为 t3
,因此输出必须为 51。您可以在以下代码中测试这一点:
@echo off
setlocal
set t1=3
set t2=1
set t3=5
echo %t1%%t2%%t3%
(
set "rest2=%t1%"
set "t1=%t3%"
set "t3=%rest2%"
)
echo %t1%%t2%%t3%
我建议您仔细检查您的代码,寻找其他部分的错误。
如果问题是代码在括号中,那么解决它的方法是通过延迟扩展,正如 rojo 在他的回答中所解释的那样。但是,如果括号中的代码是而不是,那么你应该知道你可以实现t1
和t3
的交换rest2
辅助变量 只要你把两个赋值放在同一行:
set "t1=%t3%" & set "t3=%t1%"
这是有效的,因为在执行结果行之前用百分比括起来的变量被它们的值替换。