批处理文件中的字符串替换(星号)?

4

我该如何在批处理文件中将字符串中的星号替换为其他内容?

如果 From*,那么 %MyVar:From=To% 的正常扩展似乎不起作用。

也就是说,如果我有以下内容:

Set MyVar=From

那么这些就不起作用:

Echo %MyVar:*=To%
Echo %MyVar:^*=To%

这应该如何正确完成?

7个回答

9
一个类似Sorpigal的解决方案,但它也处理以星号开头和多个星号替换的文本,并且不会因引号而失败。
@echo off
setlocal EnableDelayedExpansion
rem replace all "*" with "."
set "replace=."
set "var=*One**two***three"

rem Add dummy char to accept also a star in front
set "var=#!var!"
:replaceLoop
for /F "tokens=1 delims=*" %%A in ("!var!") do (
  set "prefix=%%A"
  set "rest=!var:*%%A=!"
  if defined rest (
    set "rest=!REPLACE!!rest:~1!"
    set Again=1
  ) else set "Again="
  set "var=%%A!rest!"
)
if defined again goto :replaceLoop
set "var=!var:~1!"
echo !var!
exit /b

你总是让人惊叹不已,非常棒! - Andriy M
谢谢,但我几个月前在一个更“实验性”的论坛上问过同样的问题如何替换变量中的“=”,“*”,“:” - jeb
嗯,我能说什么呢……我很高兴你有一个好的资源,可以帮助你惊艳像我这样的人!:) 我曾经非常喜欢批处理脚本,但我缺乏坚持。而且那时候是DOS时代,批处理脚本的功能似乎非常有限,所以我很快就放弃了。简而言之,我仍然喜欢并使用批处理脚本,因为相对简单的脚本可以节省相当多的时间。但是你在答案和评论中展示的水平完全不同,我相信仅仅参加相关论坛是不够的。 - Andriy M
1
@jeb:这太惊人了(虽然有点难以理解 :P)。非常感谢您提供的解决方案!! :) - user541686

3

总有一种方法(尽管可能不那么令人愉快)

@echo off
set myvar=one two * four
set replacement=three

for /f "tokens=1,2 delims=*" %%a in ("%myvar%") do (
    set tmp1=%%a
    set tmp2=%%b

    echo %tmp1%%replacement%%tmp2%
)

谢谢你的回答!不幸的是,如果字符串中有引号,这似乎不起作用...或者我做错了什么。有什么想法吗? - user541686

1
@echo off
setlocal EnableDelayedExpansion

set old_str=**hello * world ** 
set oldchar=*
set newchar=$
set new_str=

>$1 (<nul,set/P=%old_str%)
For %%a in ($1) do set /A cnt=%%~za
>$2 (For /l %%a in (1 1 %cnt%) do <nul,set/P=µ)

For /f "tokens=3" %%a in ('"fc /b $2 $1|findstr :"') do (
    set /A dec=0x%%a
    %ComsPec% /c exit /b !dec!
    if "!=ExitCodeAscii!"=="%oldchar%" (
       set new_str=!new_str!%newchar%
      ) else (
       set new_str=!new_str!!=ExitCodeAscii!
      )
)
del $?
echo %old_str%
echo %new_str%
pause

+1,有趣的方法,但是稍微解释一下会更好。顺便说一句,它会去掉old_str开头的空格。而且我的文本中总是有10µA100µs,所以fc也会失败 :-) - jeb

1

在 Windows XP 上测试的变体:

@echo off  1>nul 2>nul 3>nul 4>nul

set string=**hello*World**
set old_char=*
set new_char=#

pushd %Temp%.\

set string>f1.t

copy nul+nul f0.t 

for /f %%a in (f0.t) do (
  (
    echo 1r%old_char%%%a%new_char%
    echo w
    echo e
  ) | edlin /b f1.t
)
for /f "tokens=*" %%i in (f1.t) do set %%i

echo %string% >con

del f0.t f1.t f1.bak

popd
pause

1

@Mehrdad: edlin 在 XP 中可用:

hh.exe ntcmds.chm::/edlin.htm
hh.exe ntcmds.chm::/edlin_subcmds.htm

另一种变体:

@echo off
setlocal EnableDelayedExpansion

set string=**hello * World**
set old_char=*
set new_char=#
set new_str=

for /l %%a in (0 1 0xFF) do (
  if !string:~%%a^,1!. neq %old_char%. (
     set "new_str=!new_str!!string:~%%a,1!"
  ) else if !string:~%%a^,1!. neq . (
     Set new_str=!new_str!%new_char%))

echo !new_str!
pause

1

另一个:

@echo off

set str=**hello ** world**
set old=\*
set new=#

for /f "useback delims=" %%_ in (`@mshta "about:<script>var string='%str%';new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(string.replace(/%Old%/g,'%New%'));close();</script>" ^|more`) do set res=%%_

echo %str% 
echo %res%

pause

0

PS+BATCH

@echo off

set string=*hello***lop*
set oldchar=*
set newchar=$

for /f "tokens=*" %%* in ('
   "powershell -c ""$env:string"".replace('%oldchar%','%newchar%')"
 ') do set result=%%*

echo %result%
pause
goto :eof

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接