Extract leading numbers from string in batch script

I am new to batch scripting. although I have shell and python solutions for this problem, but they are stuck in a batch script.

I have a string like 123_happy , 234.healthy , 3456wealthy , etc.

I want to extract leading numbers from each line. the only pattern here is that all of these lines contain numbers at the beginning.

I cannot use echo %str:~0,3% , since it does not meet my requirement.

+6
source share
6 answers

Another option

 @echo off setlocal enableextensions disabledelayedexpansion call :extractLeadingNumbers 123_happy leadingNumbers echo %leadingNumbers% call :extractLeadingNumbers 234.healthy leadingNumbers echo %leadingNumbers% call :extractLeadingNumbers "3456wealthy" leadingNumbers echo %leadingNumbers% goto :eof rem This extracts the first numerical serie in the input string :extractLeadingNumbers inputString returnVar setlocal enableextensions disabledelayedexpansion rem Retrieve the string from arguments set "string=%~1" rem Use numbers as delimiters (so they are removed) to retrieve the rest of the string for /f "tokens=1-2 delims=0123456789 " %%a in ("%string:^"=%") do set "delimiters=%%a%%b" rem Use the retrieved characters as delimiters to retrieve the first numerical serie for /f "delims=%delimiters% " %%a in ("%string:^"=%") do set "numbers=%%a" rem Return the found data to caller and leave endlocal & set "%~2=%numbers%" goto :eof 
+7
source

I think this is the easiest way:

 @echo off setlocal set "str=123_happy" set /A num=str echo Result = %num% 

When the set /A command receives a value from a variable, it converts the number to the first character without digits without errors.

To preserve left zeros:

 set "str=0128_happy" set "num=1%str%" set /A num=num set "num=%num:~1%" echo Result = %num% 
+10
source

perhaps the easiest and fastest way:

 set z=123_happy for /l %%# in (%z%,1,%z%) do echo %%# 

this will leave only leading numbers. Although it is limited to integers 32b. As a subroutine (will not work if the input contains delimiters):

 :extractLeadingNumbers input [rtrnVar] for /l %%# in (%~1;1;%~1) do ( if "%~2" neq "" ( set "%%#=%~2" ) else ( echo %%# ) ) 

More reliable way (which will also remove leading zeros):

 cmd /c exit /b 123_happy echo %errorlevel% 
+7
source

Loop (1 => 1000 should be enough;)) on the characters of the variable and find the first char not in the range of numbers. Extract substring before:

 @echo off set z=123_happy setlocal enabledelayedexpansion set result= for /L %%i in (0,1,1000) do ( set zz=!z:~%%i,1! if x!zz!==x exit /b if !zz! lss 0 ( set result=!z:~,%%i! goto out ) if !zz! gtr 9 ( set result=!z:~,%%i! goto out ) ) :out echo result=!result! 

result:

 result=123 
+4
source

I prefer to answer Jean-Francois, but the next option is a hacker way to do this. It relies on testing for the success or failure of the set /a command. We test all the longer initial parts of the string until we can, and then we know that the previous attempt was correct.

 @echo off rem Prints the numbers in front of a string variable. rem IMPORTANT - this batch file must have a .cmd extension (NOT a .bat) setlocal enabledelayedexpansion call :getnumbers 123_happy call :getnumbers 234.healthy call :getnumbers 3456wealthy exit /b :getnumbers set s=%1 for /l %%i in (1 1 999) do ( set substr=!s:~0,%%i! set /an=!substr! 2>nul if errorlevel 1 goto :getnumbers_exitloop ) :getnumbers_exitloop echo The number in front of %1 is %n% 
+2
source

How about this:

 @echo off setlocal EnableExtensions DisableDelayedExpansion rem // Define the string here: set "STR=123_happy" setlocal EnableDelayedExpansion rem // Get first character behind the numeric part: for /F delims^=0123456789^ tokens^=*^ eol^= %%F in ("!STR!") do ( endlocal set "SEP=%%F" setlocal EnableDelayedExpansion if defined SEP set "SEP=!SEP:~,1!" ) rem // Split the string at the character behind the numeric part: if not defined SEP goto :SKIP for /F eol^=^%SEP%^ delims^=^%SEP% %%N in ("0!STR!") do ( endlocal set "STR=%%N" setlocal EnableDelayedExpansion set "STR=!STR:~1!" ) :SKIP rem // Return the numeric part: echo(!STR! endlocal endlocal exit /B 

The basic idea is to get the first character after the numeric part, which is used as a separator for the for /F loop that processes the input string. This has the great advantage that the limit for signed 32-bit integers is not applied, unlike approaches using set /A or for /L In addition, leading zeros do not inadvertently interpret as octal numbers, since this script treats the numeric part as a string.

+1
source

All Articles