当它包含特殊字符时,我对Windows批处理字符串和子字符串的批处理方式感到困惑。
我从脚本中获得了此变量:
echo "%longString"
返回我的
"<p style="text-align: center;"><a class="more" href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">Download</a></p><p style="text-align: center;"><a href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">64-Bit Graphical Installer (462 MB)</a></p><p style="text-align: center;"><a href="https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86.exe">32-Bit Graphical Installer (410 MB)</a></p></div>"
我唯一感兴趣的部分是在a href="
和">64-Bit Graphical
之间。
然后,使用类似的question(但我不包含特殊字符的困难),我尝试了所提出解决方案的许多组合,但是每次遇到特殊字符时,我的案子都得到意外的结果。
我认为不可行的例子可能是
@ECHO OFF
:: define the longstring
Call Set "longString=<p style="text-align: center;"><a class="more" href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">Download</a></p><p style="text-align: center;"><a href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">64-Bit Graphical Installer (462 MB)</a></p><p style="text-align: center;"><a href="https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86.exe">32-Bit Graphical Installer (410 MB)</a></p></div>"
:: Define subtrings token
Set "subsA=a href=""
Set "subsB=>64-Bit Graphical"
:: Remove part before subsA
Call set "Result=%%longString:*%subsA%=%%"
:: extract part to remove behind subsB
Call set "Remove=%%Result:*%subsB%=%%"
:: remove part behind subsB
Call set "Result=%%Result:%Remove%=%%"
Echo "%Result%"
目前,我最好的结果是使用Set "subsA=href"
和Set "subsB=64-Bit"
(因此更简单,因为其中没有特殊字符),这使我可以进行Result
的第一个设置和Remove
,但是因为这些新变量包含许多特殊字符,所以Result
的最后设置给我带来了麻烦。
我也尝试使用For /F
和findstr
,但结果甚至更糟。
所以我很想找到任何解决方案或解释。
答案 0 :(得分:2)
好吧,由于您尝试提取通常不应该包含引号的URL,因此可以执行以下操作:
setTextContent(String)
(为了从sub-string substitution开始使用,我故意从此搜索字符串中删除了a href="
,因为="
分隔了搜索并替换字符串); =
个字符,然后提取第二部分(第一部分为"
); 这是一个可能的解决方案:
=
答案 1 :(得分:1)
不要将call
与特殊字符一起使用,只会变得更糟(在这种情况下,即使CALL也可以使用,但这仅是运气)。
Set "longString=<p style="text-align: center;"><a class="more" href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">Download</a></p><p style="text-align: center;"><a href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">64-Bit Graphical Installer (462 MB)</a></p><p style="text-align: center;"><a href="https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86.exe">32-Bit Graphical Installer (410 MB)</a></p></div>"
最好使用延迟扩展,因为延迟扩展的结果对于所有字符都是安全的。
即使第一部分失败
:: Define subtrings token
Set "subsA=a href=""
:: Remove part before subsA
set "Result=!longString:*%subsA%=!"
这里的问题是subA a href="
中的等号,第一个等号用作search=replace
表达式中的定界符。
最好将搜索字符串更改为仅Set "subsA=a href"
。
现在您已或多或少地拥有正确的字符串,只需set result=!result:~2!
就可以删除前两个字符
您删除字符串尾部的想法很好,但是不能批量使用,REMOVE
字符串中等号再次出现问题。
但是您可以简单地计算删除字符串的长度,该长度可用于按位置将其从结果中删除。
但是remove_len中的长度太短,因为缺少了subsB本身的长度。
set "remove=!result:*%subsB%=!"
call :strlen remove_len remove
set "result=!result:~0,-%remove_len%!"
echo !result!
要感到惊讶,可以使用类似SO:How do you get the string length in a batch file?
的函数结果代码如下
@echo off
setlocal
Set "longString=<p style="text-align: center;"><a class="more" href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">Download</a></p><p style="text-align: center;"><a href=" https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86_64.exe">64-Bit Graphical Installer (462 MB)</a></p><p style="text-align: center;"><a href="https://repo.anaconda.com/archive/Anaconda3-2019.10-Windows-x86.exe">32-Bit Graphical Installer (410 MB)</a></p></div>"
setlocal EnableDelayedExpansion
:: Define subtrings token
Set "subsA=a href"
Set "subsB=>64-Bit Graphical"
:: Remove part before subsA
set "Result=!longString:*%subsA%=!"
set "Result=!result:~2!"
set result
set "remove=!result:*%subsB%=!"
set remove
call :strlen remove_len remove
call :strlen subsB_len subsB
set /a remove_len+=subsB_len+1
set "result=!result:~0,-%remove_len%!"
echo !result!
exit /b
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
(set^ tmp=!%~2!)
if defined tmp (
set "len=1"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!tmp:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "tmp=!tmp:~%%P!"
)
)
) ELSE (
set len=0
)
)
(
endlocal
set "%~1=%len%"
exit /b
)