Sign in to follow this  
Followers 0
CiVQ

StringInStr limiting search string length when searching from right

37 posts in this topic

Hello.

I know, that other approaches can be used, but this question refers strictly to the StringInStr function only!

 

So, I have a string: $sString = "Begin Begin Begin Text End End End"

(Begin's and End's in the string are testing patterns)

I want to search for the second occurrence of "End" from the right (from the end of the string).

But I want to limit the search length for that part of the string, which doesn't contain Begin's.

So, the string is: "Begin Begin Begin Text End End End",

but I want to search in: "Text End End End"

My problem is, that StringInStr returns 0, when I try to limit the search length.

This only occurrs, when searching from right (occurrence < 0).

My code:

Local $sString = "Begin Begin Begin Text End End End"
Local $iCount

; first test: searching for the second " End" from the end of string (right)
$iCount = StringInStr($sString, " End", 0, -2)
ConsoleWrite("First: "&StringTrimRight($sString, StringLen($sString)- $iCount))
ConsoleWrite(@TAB&"$iCount: "&$iCount&@CRLF)

; second attempt: setting start to 18, and limiting the search length to 16
$iCount = StringInStr($sString, " End", 0, -2, 18, 16)
ConsoleWrite("Second: "&StringTrimRight($sString, StringLen($sString)- $iCount))
ConsoleWrite(@TAB&"$iCount: "&$iCount&@CRLF)

StringInStr($sString, " End", 0, -2, 18, 16):

18 = StringLen("Begin Begin Begin ")

16 = StringLen($sString) - StringLen("Begin Begin Begin ")

 

Is this a bug, or am I missing something?

Any ideas?

Best Regards:

CiV


I know that my code is ugly. But it works. Mostly.

Share this post


Link to post
Share on other sites



it seems a malfunctioning of the function.

(here an attempt of workaround)

Local $sString = "Begin Begin Begin Text End End End"
Local $iCount

; first test: searching for the second " End" from the end of string (right)
$iCount = StringInStr($sString, " End", 0, -2)
ConsoleWrite("First: " & StringTrimRight($sString, StringLen($sString) - $iCount))
ConsoleWrite(@TAB & "$iCount: " & $iCount & @CRLF)

; second attempt: setting start to 18, and limiting the search length to 16
; $iCount = StringInStr($sString, " End", 0, -2, 18, 16)
$iCount = StringInStr(StringRight($sString, StringLen($sString) - 18), " End", 0, -1) + 18 ; <-- workaround
ConsoleWrite("Second: " & StringTrimRight($sString, StringLen($sString) - $iCount))
ConsoleWrite(@TAB & "$iCount: " & $iCount & @CRLF)

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

Thanks for the answers.

@PincoPanco: So, the StringInStr function may be buggy?

Or just an overlooked (missing) feature.

 

I know, that other approaches can be used, but this question refers strictly to the StringInStr function only!

Basically I was courious about the StringInStr function (not) functioning.

Well, let's hope, this "feature" wil be circumvented.

BR.

CiV.


I know that my code is ugly. But it works. Mostly.

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

It looks like the StringInstr() parameter 5 is the position the search starts and parameter 6 the number of characters searched.

Since you search backwards you need to set Paramater 5 to the last character like:

$iCount = StringInStr($sString, " End", 0, -2, StringLen($sString), 16)

Jos

Edited by Jos

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

Ah!

This situation remembers me a joke.

But it would be off to write it, so simply thanks.

Anyways, I again have learned some new.

Thanks, CiV.


I know that my code is ugly. But it works. Mostly.

Share this post


Link to post
Share on other sites

so, now is clearer to me too,  you have to think in reverse order.
if you do the search from left to right, the starting point is to the left, but if you do the search from right to left, the starting point is to the right.
But there is still something not very clear on the parameter "count",
In fact, if you specify for example 34 as starting point and 18 as "count"  and you try to seek the word "Begin", that is outside the search zone,  this is found although only the letter "n" is in the search area. so the effective search area is "count" + the length of the searched word - 1 instead of only the "count" parameter.
try to see.

$sString = "Begin Begin Begin Text End End End"
Local $iCount
; search from right to left
; setting start to 34, and limiting the search length to 18 chars
; the word "Begin" is found also if outside the search zone
$iCount = StringInStr($sString, "Begin", 0, -1, 34, 18)
ConsoleWrite("string found at position: " & $iCount & @CRLF)

#cs
             1         2         3   3
    1234567890123456789012345678901234
    Begin Begin Begin Text End End End
                    ----------------<-  <-- searchin right to left
                    1       1               starting point is 34
                    876543210987654321      len is 18 in this case

#ce

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

So, if at least the last character of the searched pattern is inside the searched string (from the right),

the pattern is evaluated as found, even if it's not (entirely) inside the searched string count thing.


I know that my code is ugly. But it works. Mostly.

Share this post


Link to post
Share on other sites

from my test it seems so,
it finds the string at position 13, altough position 13 is outside the search zone. (only the letter "n" is inside)


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Just throwing this out there, since I'm not clear on your question:

Local $sString = "Begin Begin Begin Text End End End"
$iText = StringInStr($sString, " Text")
$i2ndEnd = StringInStr($sString, " End",0,2,$iText)
$i2ndEndRelativeToText = $i2ndEnd-$iText
ConsoleWrite($i2ndEndRelativeToText & @CRLF)
ConsoleWrite(StringMid($sString,$iText,$i2ndEndRelativeToText) & @CRLF)

What exactly do you want as your final integer/final string?

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

 

so, now is clearer to me too,  you have to think in reverse order.

if you do the search from left to right, the starting point is to the left, but if you do the search from right to left, the starting point is to the right.

But there is still something not very clear on the parameter "count",

In fact, if you specify for example 34 as starting point and 18 as "count"  and you try to seek the word "Begin", that is outside the search zone,  this is found although only the letter "n" is in the search area. so the effective search area is "count" + the length of the searched word - 1 instead of only the "count" parameter.

try to see.

$sString = "Begin Begin Begin Text End End End"
Local $iCount
; search from right to left
; setting start to 34, and limiting the search length to 18 chars
; the word "Begin" is found also if outside the search zone
$iCount = StringInStr($sString, "Begin", 0, -1, 34, 18)
ConsoleWrite("string found at position: " & $iCount & @CRLF)

#cs
             1         2         3   3
    1234567890123456789012345678901234
    Begin Begin Begin Text End End End
                    ----------------<-  <-- searchin right to left
                    1       1               starting point is 34
                    876543210987654321      len is 18 in this case

#ce

I don't believe that is correct, 34 is first char, and 18 chars left of that is out of bounds, so I'm assuming the whole string is used.

EDIT:

I take that back, because if you search for the 2nd occurrence it's not found.

Something is wrong with the position or internal length of the string.

Edited by JohnOne

AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

how do you use the "count" parameter to search only in the last 18 characters? (starting at position 34 ofcourse) and searching right to left

Edited by PincoPanco

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

does anyone know if the wrong behavior in >post #9 is due to an incorrect use of the function StringInStr() or is due to a malfunction of the function?


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

The third param is relative from the left of the string, even if 'searching' from the right.


IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

The third param is relative from the left of the string, even if 'searching' from the right.

 

             :blink: ??

Edited by PincoPanco

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Run this:

ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,1) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,2) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,3) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,4) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,5) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,6) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,7) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,8) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,9) & @CRLF)
ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","a",0,-2,10) & @CRLF)

The start parameter determines where to begin the search from (the last one starts 10 characters in from the left, to find the second instance going left from that start point)

10 Character in from the starting point would be: aaaaabbbbb

Finding the -2nd instance of a would return: aaaaabbbbb, which is 4

example using the start param as 3:

3 characters in from the starting point: aaa

Finding the -2nd instance would return: aaa, which is 2

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

Similar to jdelaneys...

local $str = "End End Begin Begin Begin Text End End End"
ConsoleWrite(        _
    stringinstr(     _
        $str,        _                      ; string to search (1ST parm)
        'End',       _                      ; what to search for (2ND parm)
        0,           _                      ; case sense (3RD parm)
        2,           _                      ; which ocurrence of the searched for string to find (4TH parm)
        stringinstr($str,'Begin',0,-1) _    ; starting position to search from....
        +5           _                      ; plus the length of the string ('Begin') to get the starting pos for the outer search
        ) & @LF)

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Share this post


Link to post
Share on other sites

#20 ·  Posted (edited)

the problem is related to the last parameter "count" that you are not using in your examples:
StringInStr ( "string", "substring" [, casesense = 0 [, occurrence = 1 [, start = 1 [, count]]]] )

and the problem arise when searching from right to left

in this example, "underscored" characters should be the search zone (the count parameter)

ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","bb",0,1,1,6) & @CRLF) ; search left to right
; limit search to 6 chr   ------    "bb" not found because only one b is inside the search zone

ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","aa",0,-1,10,6) & @CRLF) ; search right to left
; limit search to 6 chr       ------      "aa" is found also if only one a is in search zone
;

Local $iCount = StringInStr("Begin Begin Begin Text End End End", "Begin", 0, -1, 34, 18)  ; search right to left
; limit search to 18 chr                     ------------------
ConsoleWrite("string found at position: " & $iCount & " outside the search zone" & @CRLF)

in red is the zone where the function should limit the search

but in the searching from right to left this limit is not respected correctly

ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","bb",0,1,1,6) & @CRLF) ; search left to right
; limit search to 6 chr   ------    "bb" not found because only one b is inside the search zone

; this is correct when search is left to right

ConsoleWrite(StringInStr("aaaaabbbbbbcccccddddd","aa",0,-1,10,6) & @CRLF) ; search right to left
; limit search to 6 chr       ------      "aa" is found also if only one a is in search zone
; and the result of search is outside the search zone. this is wrong

Local $iCount = StringInStr("Begin Begin Begin Text End End End", "Begin", 0, -1, 34, 18)  ; search right to left
; limit search to 18 chr                     ------------------
the word "Begin" is found but is clearly outside the search zone

Edited by PincoPanco

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0