区分大小写的字符串操作

String Manipulation with case sensitivity

假设我们有一个变量;

set test=This is a Test string.

我们想用大写字母 X 替换每个小写字母 t 所以需要的输出;

This is a TesX sXring.

我尝试使用字符串操作 set test=%test:t=X% 但它用 X 替换了每个 t。我也尝试了来自@dbenham 的JREPL.bat,但无法解决。

要保持​​纯批处理,可以做一个char by char区分大小写的比较:

@ECHO OFF
SETLOCAL EnableDelayedExpansion

SET String=This is a test.
SET "Result="

REM Process each char.
FOR /L %%A IN (0,1,999) DO (
    SET Char=!String:~%%A,1!
    REM Case sensitive char replacement.
    IF "!Char!" EQU "t" SET Char=X

    REM Append result.
    SET Result=!Result!!Char!
)

REM Output will be: This is a XesX.
ECHO %Result%

ENDLOCAL

没有可以方便地进行区分大小写的字符串操作的本机批处理命令。本机批处理解决方案必须在循环中逐个字符地构建新字符串。非常可行 - 但很痛苦而且效率低下。

编辑 - 很久以前我写了一个名为 modFile.bat 的纯批处理实用程序,它对文本文件的内容区分大小写 find/replace。性能还不错,但确实有一些限制。我很少使用该代码。我已经编写了一个配套例程来对变量而不是文本文件执行区分大小写的 find/replace,但我似乎丢失了该代码。

今天,每当我想操作文本时,我几乎总是使用 JREPL.BAT

您的示例的 JREPL.BAT 解决方案应该是:

for /f delims^=^ eol^= %%A in ('jrepl t X /s test') do set "test=%%A"

不过好像有bug。如果变量名是 test 以外的某个名称,它会起作用。看来我有一些调试要做。

bug修复前,您可以使用:

for /f delims^=^ eol^= %%A in ('cmd /v:on /c "echo(!test!)|jrepl t X"') do set "test=%%A"


更新:该错误已在 3.4 版本中修复 /S 选项现在可用于一个名为 TEST.

的变量

如果您不需要完整的 jrepl.bat 功能,您可以制作自己的混合批处理脚本来使用 JScript 的 String.prototype.replace() 功能。

@if (@CodeSection == @Batch) @Then
@echo off
setlocal

set test=This is a Test string.

:: invoke JScript and capture result to %test%
for /f "delims=" %%I in ('cscript /nologo /e:Jscript "%~f0" "%test%"') do (
    set "test=%%I"
)

echo %test%

goto :EOF

:: end batch / begin JScript
@end

WSH.Echo(WSH.Arguments(0).replace(/t/g, 'X'));

输出:

This is a TesX sXring.

或者,如果您不介意 PowerShell 命令,-creplace 会进行区分大小写的替换。

@echo off
setlocal

set test=This is a Test string.
set psCommand=powershell -command "'%test%' -creplace 't','X'"

for /f "delims=" %%I in ('%psCommand%') do set "test=%%I"

echo %test%

相同的输出。

我不认为下面的纯 Batch 解决方案效率低下(仅用两行 no 循环就实现了替换)。它唯一的限制是它最多替换字符串中的 25 个字母:

编辑:我修复了一个错误,该错误错误地替换了几个由一个替换字母连接在一起的搜索字母。

@echo off
setlocal EnableDelayedExpansion

set find=t
set repl=X

rem Prepare the replacement auxiliary variables (just once)
set "join=%%a"
for %%a in (b c d e f g h i j k l m n o p q r s t u v w x y z) do set "join=!join!%repl%%%%%a"

rem First method: fail when two search letters are joined together
set test=This is a Test string.

echo Input:  %test%
echo Change "%find%" by "%repl%":
for /F "tokens=1-26 delims=%find%" %%a in ("%test%¡") do call set "out=%join%"
for /F "delims=¡" %%a in ("%out%") do set "out=%%a"
echo Output: %out%

echo/

rem Second method: previous bug fixed
set test=This Test String Have Two "t" Letters joined Together.

echo Input:  %test%
echo Change "%find%" by "%repl%":
for /F "tokens=1-26 delims=%find%" %%a in ("!test:%find%%find%=%find%¿%find%!¡") do call set "out=%join%"
for /F "delims=¡" %%a in ("%out%") do set "out=%%a"
set "out=!out:%repl%¿%repl%=%repl%%repl%!"
echo Output: %out%

输出:

Input:  This is a Test string.
Change "t" by "X":
Output: This is a TesX sXring.

Input:  This Test String Have Two "t" Letters joined Together.
Change "t" by "X":
Output: This TesX SXring Have Two "X" LeXXers joined TogeXher.