How to Check if a String Starts With a Specific Substring in Batch Script
A common requirement in scripting is to determine if a string begins with a specific prefix or sequence of characters. This is essential for parsing input, validating data formats, or performing conditional logic based on a string's starting pattern. Unlike higher-level languages that have built-in startsWith()
functions, Windows Batch requires a more creative approach.
This guide will thoroughly dissect a clever and effective technique that uses Batch's string substitution capabilities to reliably check if one string starts with another. We'll break down the logic behind the method, provide a reusable subroutine, and discuss its usage and key considerations.
The Challenge: No Built-in startsWith()
Function in Batch
Many programming languages provide a simple function like string.startsWith("prefix")
to check if a string begins with a certain substring. Windows Batch does not have such a built-in command. While you can use substring extraction (%variable:~0,N%
) if the prefix has a known, fixed length, this becomes cumbersome if the prefix length can vary. The method presented here provides a universal solution regardless of the prefix length.
The Core Technique: String Substitution and Comparison
This method relies on a clever "search and replace" logic to determine if the prefix exists at the very start of the main string.
The Logic Explained
- Prefix the Main String: We take our main string (
string1
) and add a unique, known prefix to it that is guaranteed not to appear anywhere in the original strings. Let's use@@@
for this example. Our new string becomes@@@string1
. - Attempt to Remove the Prefix Combo: We then perform a string substitution on this new string, attempting to replace the sequence
@@@
followed by the prefix we're checking for (string2
). - Compare the Results:
- If
string1
does start withstring2
, our new string@@@string1
will actually be@@@string2...
. The substitution will find and remove@@@string2
, altering the string. - If
string1
does not start withstring2
, the exact sequence@@@string2
will not be found at the beginning of@@@string1
. The substitution will do nothing, and the string will remain unchanged. - By comparing the string before and after the attempted substitution, we can determine if the replacement happened, which tells us if the string started with the specified prefix.
- If
The Script Snippet
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
set "string1=Hello World!"
set "string2=Hello"
set "s=@@@%string1%"
if "%s%"=="!s:@@@%string2%=!" (
echo."%string1%" does NOT begin with "%string2%"
) ELSE (
echo."%string1%" begins with "%string2%"
)
Output:
"Hello World!" begins with "Hello"
2.3. How It Works: A Detailed Breakdown
Let's trace the example string1="Hello World!"
and string2="Hello"
:
SETLOCAL ENABLEDELAYEDEXPANSION
: This is crucial for the string substitution syntax using!
.set "s=@@@%string1%"
: The variables
becomes"@@@Hello World!"
.- The
IF
statement compares two values:- Left side:
"%s%"
. At parse time, this is replaced with the value ofs
, so it becomes"@@@Hello World!"
. - Right side:
"!s:@@@%string2%=!"
. This is where delayed expansion and string substitution happen.!s...
: The!
triggers delayed expansion, using the current value ofs
.:@@@%string2%=
: This is the substitution part. It means "in the strings
, replace the occurrence of@@@Hello
with nothing (=
is followed by nothing).- The substitution is successful, and the right side evaluates to
"! World!"
.
- Left side:
- The comparison becomes:
if "@@@Hello World!" == "! World!"
. This is false. - Because the comparison is false, the
ELSE
block is executed, correctly reporting that the string begins with the prefix.
Now, let's trace with string2="Goodbye"
:
set "s=@@@Hello World!"
(same as before).- The
IF
statement's right side is"!s:@@@%string2%=!"
, which becomes"!s:@@@Goodbye=!"
. - The substring
"@@@Goodbye"
is not found in"@@@Hello World!"
, so no replacement occurs. The right side evaluates to the original string,"@@@Hello World!"
. - The comparison becomes:
if "@@@Hello World!" == "@@@Hello World!"
. This is true. - Because the comparison is true, the
IF
block is executed, correctly reporting that the string does not begin with the prefix.
Creating a Reusable Subroutine (:stringStartsWith
)
To make this logic easily reusable, we can wrap it in a callable subroutine. This subroutine will set a "return" variable to indicate the result (1
for true, 0
for false).
The Script with a Reusable Subroutine
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
REM --- Example Usage ---
set "mainString=This is a test string."
set "prefixToCheck=This is"
CALL :stringStartsWith "%mainString%" "%prefixToCheck%" result
IF !result! EQU 1 (
ECHO SUCCESS: The string starts with the prefix.
) ELSE (
ECHO FAILED: The string does not start with the prefix.
)
ECHO.
set "prefixToCheck=is a"
CALL :stringStartsWith "%mainString%" "%prefixToCheck%" result
IF !result! EQU 1 (
ECHO SUCCESS: The string starts with the prefix.
) ELSE (
ECHO FAILED: The string does not start with the prefix.
)
GOTO :EOF
:stringStartsWith
:: Checks if string1 starts with string2.
:: %~1 [in] - The main string to check.
:: %~2 [in] - The prefix string to look for at the beginning.
:: %~3 [out] - The name of the variable to store the result (1 for true, 0 for false).
SETLOCAL
set "s=@@@%~1"
IF "%s%"=="!s:@@@%~2=!" (
SET "res=0"
) ELSE (
SET "res=1"
)
(
ENDLOCAL
SET %~3=%res%
)
EXIT /B
Output:
SUCCESS: The string starts with the prefix.
FAILED: The string does not start with the prefix.
How to Use the Subroutine
You call the subroutine with three arguments:
- The main string.
- The prefix string to check for.
- The name of a variable where you want the result stored.
CALL :stringStartsWith "MyDataFile_2024.txt" "MyData" didStart
IF %didStart% EQU 1 ECHO The filename is correct.
Important Considerations
The Need for EnableDelayedExpansion
Delayed expansion is essential for this technique. The IF
command line is parsed once, including the variable expansion !s:...=!
. Without delayed expansion, using %s:...=%
would not work correctly because %s%
would be expanded before the substitution could be evaluated with its current value.
Choosing a Safe, Non-Occurring Prefix
The special prefix you add (e.g., @@@
) must be a sequence of characters that you are absolutely certain will never appear at the beginning of your main string (string1
). If string1
could legitimately start with @@@
, the logic would fail. Choose a unique and unusual combination, like ###$$$###
or a long random string, if there's any doubt.
Case Sensitivity
This comparison is case-sensitive by default. For example, it will find that "Hello" does not start with "hello". To perform a case-insensitive check, you would need to convert both strings to the same case before comparison, which adds complexity but can be done with a FOR
loop character-by-character mapping. For most use cases, the case-sensitive check is sufficient.
Conclusion
While Windows Batch lacks a direct startsWith()
function, the string substitution method provides a clever, reliable, and universal solution for checking if a string begins with a specific substring, regardless of its length.
By temporarily prefixing the main string and attempting to replace the combined prefix and search string, you can determine the outcome by comparing the string to its original form.
Encapsulating this logic in a reusable subroutine makes it a powerful and clean addition to any batch script that needs to perform conditional actions based on string prefixes.