how can i get position of a character(s) in a string?
Moderator: DosItHelp
how can i get position of a character(s) in a string?
how can i get position of a character(s) in a string?
let the string is "This is the example."
i want to get starting position of "the".
thanks.
let the string is "This is the example."
i want to get starting position of "the".
thanks.
hgulcan,
Below a findString function and how to use it.
The result of the example is: "Position is: 8"
To try it out copy both code blocks into a new batch file.
DosItHelp?
Below a findString function and how to use it.
The result of the example is: "Position is: 8"
To try it out copy both code blocks into a new batch file.
Code: Select all
@ECHO OFF
set "s=This is the example."
call:findString s "the" pos
if not defined pos echo.Substring not found&goto:eof
echo.Position is: %pos%
goto:eof
Code: Select all
:findString -- returns the zero based postion of one string in another string of maximum length of 1023 characters
:: -- %~1: in - varible name of a string to be serached
:: -- %~1: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!%~1!"
set "str=!str:%~2=@@@@!
set "str=%str:@@@@="&REM %
if "%str%"=="!%~1!" (
ENDLOCAL&IF "%~3" NEQ "" SET "%~3="
GOTO:EOF
)
set str=A!str!& rem keep the A up front to ensures we get the length and not the upper bond
rem it also avoids trouble in case of empty string
set len=0
set /a n=1024
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
set /a n^>^>=1, len+=n
if !str:~%len%!. == . set /a len-=n
( ENDLOCAL & REM RETURN VALUES
IF "%~3" NEQ "" SET %~3=%len%
)
GOTO:EOF
DosItHelp?
Hi,
nice trick to truncate the string.
But here is a little bit better version, that work also for (should work for all strings)
set "s=This@@@@ is the example."
call:findString s "the" pos
:findString -- returns the zero based postion of one string in another string of maximum length of 1023 characters
:: -- %~1: in - varible name of a string to be serached
:: -- %~2: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!%~1!"
REM set "str=!str:%~2=@@@@!
REM set "str=%str:@@@@="&REM %
set "str=!str:%~2="!
...
btw. Has the <&rem %> part in <set "str=%str:@@@@="&REM %>
a special meaning or is the line
<set "str=%str:@@@@="%> always equivalent?
nice trick to truncate the string.
But here is a little bit better version, that work also for (should work for all strings)
set "s=This@@@@ is the example."
call:findString s "the" pos
:findString -- returns the zero based postion of one string in another string of maximum length of 1023 characters
:: -- %~1: in - varible name of a string to be serached
:: -- %~2: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
SETLOCAL ENABLEDELAYEDEXPANSION
set "str=!%~1!"
REM set "str=!str:%~2=@@@@!
REM set "str=%str:@@@@="&REM %
set "str=!str:%~2="!
...
btw. Has the <&rem %> part in <set "str=%str:@@@@="&REM %>
a special meaning or is the line
<set "str=%str:@@@@="%> always equivalent?
jeb,
- set "str=!%~1!"
str is now "This is the example"
- set "str=!str:%~2=@@@@!
str is now "This is @@@@ example"
- set "str=%str:@@@@="&REM %
this finally truncates the string, i.e. before executing it evaluates to:
set "str="This is "&REM example
so that str is now "This is ".
How does your example get rid of the stuff after "the"?
- set "str=!%~1!"
str is now "This is the example"
- set "str=!str:%~2=@@@@!
str is now "This is @@@@ example"
- set "str=%str:@@@@="&REM %
this finally truncates the string, i.e. before executing it evaluates to:
set "str="This is "&REM example
so that str is now "This is ".
How does your example get rid of the stuff after "the"?
Speaking of "better"...
Code: Select all
:findString -- returns position of first occurrence of a string in another string, case sensitive, maximum string length is 1023 characters
:: -- %~1: in - varible name of a string to be searched
:: -- %~1: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="
set "str=!%~1!"
for /L %%a in (0,1,1023) do (
set "s=!str:~%%a!"
if not defined pos if "%~2!s:*%~2=!"=="!s!" set "pos=%%a"
)
ENDLOCAL & IF "%~3" NEQ "" SET "%~3=%pos%"
GOTO:EOF
Code: Select all
:findStringNoCase -- returns position of first occurrence of a string in another string, NOT case sensitive, maximum string length is 1023 characters
:: -- %~1: in - varible name of a string to be searched
:: -- %~1: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="
set "str=!%~1!"
for /L %%a in (0,1,1023) do (
set "s=!str:~%%a!"
if not defined pos if /i "%~2!s:*%~2=!"=="!s!" set "pos=%%a"
)
ENDLOCAL & IF "%~3" NEQ "" SET "%~3=%pos%"
GOTO:EOF
Code: Select all
:findStringFromEnd -- returns position of last occurrence of a string in another string, case sensitive, maximum string length is 1023 characters
:: -- %~1: in - varible name of a string to be searched
:: -- %~1: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="
set "str=!%~1!"
for /L %%a in (0,1,1023) do (
set "s=!str:~%%a!"
if /i "%~2!s:*%~2=!"=="!s!" set "pos=%%a"
)
ENDLOCAL & IF "%~3" NEQ "" SET "%~3=%pos%"
GOTO:EOF
Code: Select all
:findStringFromEndNoCase -- returns position of last occurrence of a string in another string, NOT case sensitive, maximum string length is 1023 characters
:: -- %~1: in - varible name of a string to be searched
:: -- %~1: in - string to be found
:: -- %~3: out- return variable name, will be set to position or undefined if string not found
:$source http://www.dostips.com
SETLOCAL ENABLEDELAYEDEXPANSION
set "pos="
set "str=!%~1!"
for /L %%a in (0,1,1023) do (
set "s=!str:~%%a!"
if "%~2!s:*%~2=!"=="!s!" set "pos=%%a"
)
ENDLOCAL & IF "%~3" NEQ "" SET "%~3=%pos%"
GOTO:EOF
Hi all,
your Version
> so that str is now "This is ".
> How does your example get rid of the stuff after "the"?
My Variant simple expand to
All text after the second " will be ignored without any error.
I suppose your first solution with using of strlen is faster than the others
with "extreme searching", but dont tested it yet.
your Version
Code: Select all
set "str=!%~1!" -- str is now "This is the example"
set "str=!str:%~2=@@@@! -- str is now "This is @@@@ example"
set "str=%str:@@@@="&REM % -- this finally truncates the string, i.e. before executing it evaluates to:
-- set "str="This is "&REM example
> so that str is now "This is ".
> How does your example get rid of the stuff after "the"?
My Variant simple expand to
Code: Select all
set "str=!str:%~2="! -- expand to set "str=This is"example
All text after the second " will be ignored without any error.
I suppose your first solution with using of strlen is faster than the others
with "extreme searching", but dont tested it yet.
jeb,
Yes you are right the binary approach is much faster.
The problem with using <set "str=!str:%~2="!> is that the search string may occur multiple times, e.g. if %~2 expands to the letter h then:
which causes an error saying:
is was unexpected at this time.
When changing the example string from "This" to "That" to "That is the example" then:
which causes same error:
is was unexpected at this time.
I expected it would complain about at now, but no.
Very confusing isn't it?
Yes you are right the binary approach is much faster.
The problem with using <set "str=!str:%~2="!> is that the search string may occur multiple times, e.g. if %~2 expands to the letter h then:
Code: Select all
set "str=!str:%~2="! -- expands to set "str=T"is is t"e example
is was unexpected at this time.
When changing the example string from "This" to "That" to "That is the example" then:
Code: Select all
set "str=!str:%~2="! -- expands to set "str=T"at is t"e example
is was unexpected at this time.
I expected it would complain about at now, but no.
Very confusing isn't it?
Re: how can i get position of a character(s) in a string?
What is the trick @DosItHelp is using in this line:
set "str=%str:@@@@="&REM %
>>&REM %<< ?
and why do they prefer this
set "str=!str:%~2="!
over this ?
set "str=!str:%~2=!"
yes, I know a little about the parser, but in practice it's a lot of guessing for me.
set "str=%str:@@@@="&REM %
>>&REM %<< ?
and why do they prefer this
set "str=!str:%~2="!
over this ?
set "str=!str:%~2=!"
yes, I know a little about the parser, but in practice it's a lot of guessing for me.
-
- Expert
- Posts: 442
- Joined: 01 Aug 2010 17:13
- Location: Canadian Pacific
- Contact:
Re: how can i get position of a character(s) in a string?
Yeah, I honestly wonder about voodoo syntax like that myself. How the heck does it make any sense? lol
Re: how can i get position of a character(s) in a string?
orange_batch wrote:Yeah, I honestly wonder about voodoo syntax like that myself. How the heck does it make any sense? lol
DosItHelp is injecting a command into the string replacement processing.
----------
Have I solved all the issues? and is it worth all the code?
Code: Select all
@echo off
setlocal disableDelayedExpansion
set "str=This! &"@@@@^&"&" is the string with the multiple problems"
set "search=the"
setlocal enableDelayedExpansion
echo str=!str!
set "str=!str:"=""!"
set "cmd=set ^"str2=!str:%search%="&rem!"
echo cmd=!cmd!
setlocal disableDelayedExpansion
%cmd%
setlocal enableDelayedExpansion
set "result=!str2:""="!"
echo result=[!result!]
output:
Code: Select all
str=This! &"@@@@&"&" is the string with the multiple problems
cmd=set "str2=This! &""@@@@&""&"" is "&rem string with "&rem multiple problems
result=[This! &"@@@@&"&" is ]
Dave Benham
Addendum - Oops - should probably double up quotes in search string as well with one more search and replace.
Last edited by dbenham on 31 May 2011 17:10, edited 1 time in total.
Re: how can i get position of a character(s) in a string?
It will still take me time to figure out the exact workings, cause I need to be sure I understand it fully &so when to use it.
I am turning this forum upside down, cause it holds secrets no other sites mention.
Too bad I didn't discover Dostips in 2006. I've googled often enough for the words DOS, CMD &commandline help
Dave, thank u very much for your dedication in explaining things
I am turning this forum upside down, cause it holds secrets no other sites mention.
Too bad I didn't discover Dostips in 2006. I've googled often enough for the words DOS, CMD &commandline help
Dave, thank u very much for your dedication in explaining things
-
- Posts: 287
- Joined: 16 Mar 2011 19:17
- Location: scriptingpros.com
- Contact:
Re: how can i get position of a character(s) in a string?
Ed Dyreen wrote:I am turning this forum upside down, cause it holds secrets no other sites mention.
@Ed
What secrets do you speak of, like prizes at the bottom of a box of Captin Crunch?
Re: how can i get position of a character(s) in a string?
YES, I can't leave until I know EVERYTHING, I'm autistic
but they say it passes into other obsessions every 10 years or so.
but they say it passes into other obsessions every 10 years or so.
-
- Posts: 287
- Joined: 16 Mar 2011 19:17
- Location: scriptingpros.com
- Contact:
Re: how can i get position of a character(s) in a string?
dbenham wrote:Have I solved all the issues? and is it worth all the code?
No
It fails even with doubling the quotes, the problem is now ^"
It seems to be a general problem if you leave the quotes in the text, you got also problems with the carets.
Code: Select all
set "str=This! &"@@@@^&"&" is^^"& the string with the multiple problems"
And using the %cmd%, you always got problems with <LF> and <CR>, the <CR> are removed, and <LF> breaks the parsing immediatly.
My last solution (delayed expansion with a quote) fails with multiple occurence of the search string.
Therefore I try a new way of splitting the rest with a FOR /F and <LF> combination.
Code: Select all
@echo off
setlocal
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
set LF=^
rem TWO Empty lines are neccessary
set "str=This! &"@@@@^&"&" is^^"& the string with the multiple problems"
call :strip str "the"
setlocal EnableDelayedExpansion
goto :eof
:strip
setlocal EnableDelayedExpansion
set "var=!%~1!"
echo input=!var!
REM *** Here is the trick, we replace the SEARCH-Text with a <LF>
REM *** Later the <LF> breaks the FOR /F loop
for %%a in ("!LF!") do set "var=!var:%~2=%%~a!"
for /F "tokens=* delims=" %%1 in ("!var!") DO (
set "result=%%1"
goto :leaveLoop
)
:leaveLoop
echo result=!result!
goto :eof
To preserve the carets and exclamation marks you could use it with the "secure return" technic.
jeb