我需要在最后一个点后将变量拆分为两个较小的变量。例如,变量“ european.union
”将是vara=european
和varb=union
我使用下面的代码来实现这个目的:
for /f "tokens=1 delims=." %%a in ("%elvariato%") do set vara=%%a
for /f "tokens=2 delims=." %%a in ("%elvariato%") do set varb=%%a
问题是此代码无法管理多个“ .
”分割变量。例如,变量spain is in.the.european.union
将使此代码完全无用。
vara="spain is in"
varb=the
将是输出,但我需要vara="spain is in.the.european"
varb=union
不用担心 var 空间,我可以管理它们。
我想在最后一个点处拆分变量.
,但我不知道如何实现。我尝试读取标记总数以合并所有标记,最多 N-1 个,但没有成功。在脚本分析变量之前无法知道点数,这有点困难。有什么建议吗?
答案1
我的建议是使用 PowerShell;-)。
$text = "spain is in.the.european.union"
$vara = $text.Substring(0, $text.lastIndexOf('.'))
$varb = $text.Split(".")[-1]
输出:
PS C:\WINDOWS\system32> $vara
spain is in.the.european
PS C:\WINDOWS\system32> $varb
union
要在 cmd 脚本中使用它,这将设置%vara%
并%varb%
正确,以便在您的 cmd 脚本中进一步使用它。
for /f "delims=" %%a in (' powershell "$env:elvariato.Substring(0, $env:elvariato.lastIndexOf('.'))" ') do set "vara=%%a"
for /f "delims=" %%a in (' powershell "$env:elvariato.split('.')[-1]" ') do set "varb=%%a"
%vara%
在这种情况下包含spain is in.the.european
和%varb%
包含union
解释:
Substring(0, $text.lastIndexOf('.'))
获取从字符串开头 (0
) 到结尾的所有内容.
split('.')[-1]
在每个点上拆分字符串并获取创建的数组中的最后一个值
答案2
以下(部分注释)代码片段显示了纯批处理文件解决方案:
@ECHO OFF
rem default/expected: SETLOCAL EnableExtensions DisableDelayedExpansion
if "%~1"=="" (
set "elvariato=spain is in.the.european.union" asked example value
) else (
set "elvariato=%~1" supplied sample value
)
set "_dot_pos="
set "nodots=%elvariato:.=%" check for any dot presence
if "%nodots%"=="%elvariato%" goto :jjloopEnd
set /a jj=1
:jjloop compute last dot position (counted from the end of string)
call set "_auxiliary=%%elvariato:~-%jj%%%"
set "_aux_1char=%_auxiliary:~0,1%"
if "%_aux_1char%"=="." (
set /A _dot_pos=jj
set /A _dot_pre=jj - 1
goto :jjloopEnd
)
set /a jj+=1
goto :jjloop
:jjloopEnd
if not defined _dot_pos (
rem string does not contain any dot character at all
set "vara=%elvariato%"
set "varb="
goto :showResults
)
call set "vara=%%elvariato:~0,-%_dot_pos%%%"
if %_dot_pos% EQU 1 (
set "varb="
) else (
call set "varb=%%elvariato:~-%_dot_pre%%%"
)
:showResults
rem debugging output
echo vara="%vara%" varb="%varb%"
goto :eof
示例输出:
==> D:\bat\SU\1302882c.bat
vara="spain is in.the.european" varb="union"
==> D:\bat\SU\1302882c.bat "." a dot only
vara="" varb=""
==> D:\bat\SU\1302882c.bat "nodots"
vara="nodots" varb=""
==> D:\bat\SU\1302882c.bat ".leading dot only"
vara="" varb="leading dot only"
==> D:\bat\SU\1302882c.bat "trailing dot only."
vara="trailing dot only" varb=""
==> D:\bat\SU\1302882c.bat "1st.dot.2nd.dot.another.dot.more.dots"
vara="1st.dot.2nd.dot.another.dot.more" varb="dots"
资源(必读,未完成):
- (命令参考)Windows CMD 命令行的 AZ 索引
- (其他细节)Windows CMD Shell 命令行语法
- (
%~1
等专题页面)命令行参数(参数) - (
%_auxiliary:~0,1%
ETC。)提取变量的一部分(子字符串) - (
%elvariato:.=%
ETC。)变量编辑/替换
答案3
这可能是“作弊”,但是,只要你的分隔符是点(“.
”),您可以使用一个技巧:假装您的字符串是一个文件名:
setlocal enabledelayedexpansion
︙
for %%A in (%elvariato%) do set "vara=%%~nA" & set "varb_plus=%%~xA"
for /f "delims=. tokens=1" %%B in ("!varb_plus!") do set varb=%%B
%%~nA
并分别%%~xA
将其%%A
视为路径名并提取基本文件名部分和扩展名。基本文件名定义为直到最后一个点的所有内容,因此这就是您的vara
。扩展名是最后一个点及其后的所有内容(例如“ .txt
”),这不是您想要的。因此我们将扩展名分配给varb_plus
— 这是所需的值varb
加上一个点。然后很容易使用它for /f "delims=. tokens=1"
来获取点后的部分。
因为%%~nA
返回基本文件名部分的,如果您的完整变量包含或,%%A
这将失败。您可能能够通过查看 (的路径名部分)来处理此问题,但目前还不清楚如何做到这一点——尤其是如果它可以包含/
\
%%~pA
%%A
任何一个 /
或者\
。