我需要知道一个字符串是否以某东西开头,产生了这个小例子来解释(我使用批处理编译器/预处理器或带有高级命令的任何东西):
rem GetInput
if "%result%"=="cd *" goto Cd
:Cd
if "%result%"=="cd meow" Echo Going to directory 'meow'...
Run Code Online (Sandbox Code Playgroud)
但是此代码不起作用,如果字符串%result%以字母cd开头,则在带有“ cd *”的行中,脚本不会转到:Cd。不知道我现在是否真的可以理解,但愿意帮忙x)
谢谢,
-广场
如果我正确理解这一点,则您正在尝试确定该值是否%result%以'cd'开头,并且您未成功使用a *作为通配符来确定这一点。
有几种不同的方法可以解决此问题。这是一种方法:您可以检查前两个字符是否等于'cd':
if /i "%result:~0,2%"=="cd" goto Cd
Run Code Online (Sandbox Code Playgroud)
set /? 对此有更多了解。
标题比用例更广泛,这使得通用的startsWith对于特定问题来说有点矫枉过正——正如Wes所说,对于这个特定问题,你可以只检查前两个字符并检查cd.
但记住这一点,让我们回答标题中更通用的问题。
DOSTips.com的startsWith 解决方案看起来相当不错。
:StartsWith text string -- Tests if a text starts with a given string
:: -- [IN] text - text to be searched
:: -- [IN] string - string to be tested for
:$created 20080320 :$changed 20080320 :$categories StringOperation,Condition
:$source https://www.dostips.com
SETLOCAL
set "txt=%~1"
set "str=%~2"
if defined str call set "s=%str%%%txt:*%str%=%%"
if /i "%txt%" NEQ "%s%" set=2>NUL
EXIT /b
Run Code Online (Sandbox Code Playgroud)
这似乎可行,但它并没有真正返回值,而且它的变量名称非常 20 世纪 90 年代的风格。
我破解了这个:
:startsWith
set "haystack1=%~1"
set "needle2=%~2"
if defined needle2 call set "s=%needle2%%%haystack1:*%needle2%=%%"
if /i "%haystack1%" NEQ "%s%" (
exit /b 0
)
EXIT /b 1
Run Code Online (Sandbox Code Playgroud)
这将返回一个1in%errorlevel%表示“是”,“does-start-with”,以及“ 0no”,“does-NOT-start-with”。您可能会争辩说 does-start-with 应该返回0“无错误”。如果您有强烈的感觉,显然欢迎您在实现中交换这些内容。我会选择“零传统上是假的,因此它代表错误的返回值”。嗯,。
这是一个完整的测试示例......
@ECHO OFF
call :startsWith slappy slap
echo %errorlevel%
echo.
call :startsWith slap slappy
echo %errorlevel%
echo.
call :startsWith slappy spam
echo %errorlevel%
echo.
call :startsWith slappy lap
echo %errorlevel%
echo.
call :startsWith spam
echo %errorlevel%
echo.
exit /b 0
:startsWith
set "haystack1=%~1"
set "needle2=%~2"
set "s="
REM I think this is okay b/c if %2 was defined, %1 kinda has to be too.
if defined needle2 call set "s=%needle2%%%haystack1:*%needle2%=%%"
echo needle: %needle2%
echo haystack: %haystack1%
echo s: %s%
if /i "%haystack1%" NEQ "%s%" (
exit /b 0
)
EXIT /b 1
Run Code Online (Sandbox Code Playgroud)
needle: slap
haystack: slappy
s: slappy
1
needle: slappy
haystack: slap
s: slappyslap
0
needle: spam
haystack: slappy
s: spamslappy
0
needle: lap
haystack: slappy
s: lappy
0
needle:
haystack: spam
s:
0
Run Code Online (Sandbox Code Playgroud)
这是一个巧妙的技巧。它基本上...
needleneedle出现在 中的任何位置,则将出现在 出现之后haystack的部分添加到新字符串中。否则将所有添加到新字符串中。haystickneedlehaystackhaystack,你就赢了!否则你就输了。因此,如果needle是slap并且haystack是slappy,%s%则将slap加上[slap其中后面的所有内容slappy都是...] py。这给了我们slappy,它与 中的内容相匹配haystack,我们赢了。
如果 Needle 是spam, haystack 是slappy,%s%将从 开始spam,然后,因为spam不在 中,所以slappy我们添加所有haystack。这让我们留下了spamslappy,我们也失去了。(spamslappy?这就是喜剧。)
当您查找位于 中但不在 开头的内容时haystack,就像我们的示例一样,就会失败lap。也就是说,如果针是 ,lap干草堆是slappy,%s%将从 开始,然后,从inlap结尾开始的所有内容也给出,我们有加号或,但不是,我们再次失败,但以一种新的、很酷的方式。lapslappypylappylappyslappy
参数引用删除。命令行参数之前的波浪号(例如
"%~1")表示从参数中删除周围的引号。如果 的值%1是"Hi"那么%~1将扩展到仅Hi。
call set "s=%str%%%txt:*%str%=%%"有点复杂。
首先了解冒号(:)意味着我们正在使用“字符串替换功能”:
此代码取自同一页面,替换needs为hasin %str:
set str=%str:needs=has%
echo %str%
Run Code Online (Sandbox Code Playgroud)
那么我们需要知道...
“StrToFind”[在
:]之后可以以星号开头,在这种情况下,它将替换“StrToFind”左侧的所有字符。
...Run Code Online (Sandbox Code Playgroud)::Delete the character string 'ab' and everything before it SET _test=12345abcabc SET _result=%_test:*ab=% ECHO %_result% =cabc
然后看这个答案:
那里
call会导致另一层变量扩展,因此有必要[转义]原始%符号,但最终一切都会解决。
现在call set "s=%str%%%txt:*%str%=%%"应该有道理了。
该问题的另一个答案表明,DOSTips 中的startsWith 方法比此处的其他答案稍微不那么挑剔,因为......
您可以使用 !,但必须设置 ENABLEDELAYEDEXPANSION 开关。
我们正在避免这种情况。
最后...
如果您对所有这些神秘规则的疯狂感到震惊,那么您应该学习 PowerShell,它太棒了!
哈!好的,但我们仍然可以在不离开批次的情况下完成它。享受!