JohnOne Posted January 28, 2015 Share Posted January 28, 2015 (edited) I find myself needing a function similar to _StringBetween but also to return the positions of any strings found. I've searched for this without any luck, but before I start to write one, just wondering if anyone has seen such a function around the forum? Edited January 30, 2015 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted January 28, 2015 Author Share Posted January 28, 2015 (edited) So far I have my _StringsInStr func It will be mutilated to _StringBetweenEx soon, so I'll put it here for posterity. #cs $Array = _StringsInStr("The mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad land", "mad") If Not IsArray($Array) Then Exit MsgBox(0, 0, 0) EndIf _ArrayDisplay($Array) #ce Func _StringsInStr($SearchIn, $SearchFor) Local $Size = 10 Local $aPos[$Size], $Found = 0, $Index = 0 Do $Found = StringInStr($SearchIn, $SearchFor, 0, 1, $Found + 1) If $Found Then If $Index = $Size Then $Size += $Size ReDim $aPos[$Size] EndIf $aPos[$Index] = $Found $Index += 1 EndIf Until $Found = 0 Or @error If $Index = 0 Then Return SetError(1, 0, 0) EndIf ReDim $aPos[$Index] Return $aPos EndFunc ;==>_StringsInStr Edited January 28, 2015 by JohnOne AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Gianni Posted January 28, 2015 Share Posted January 28, 2015 (edited) ... string between and position where found this old listing has a bug (that is: if a string inside delimiters is also outside of delimiters it returns a wrong position) #include <Array.au3> #include <String.au3> Example() Func Example() $sMyString = "[18]zero[20]hello[18]example[5]one[500]two[60]" $aResult = _StringBetweenAndPos($sMyString) _ArrayDisplay($aResult) EndFunc ;==>Example ; Func _StringBetweenAndPos($sMyString) Local $aArray = _StringBetween($sMyString, "[", "]") If @error Then Return SetError(1, 0, "") Local $aResult[UBound($aArray)][2], $iStart = 1 For $i = 0 To UBound($aArray) - 1 $aResult[$i][0] = $aArray[$i] $aResult[$i][1] = StringInStr($sMyString, $aResult[$i][0], 0, 1, $iStart) $iStart = $aResult[$i][1] + 1 Next Return $aResult EndFunc ;==>_StringBetweenAndPos #include <Array.au3> #include <String.au3> Example() Func Example() $sMyString = "[18]zero[20]hello18[18]example[5]one[500]two[60]" $aResult = _StringBetweenAndPos($sMyString, "[", "]") _ArrayDisplay($aResult) EndFunc ;==>Example Func _StringBetweenAndPos($sMyString, $sDelim1, $sDelim2) Local $aArray = _StringBetween($sMyString, $sDelim1, $sDelim2) If @error Then Return SetError(1, 0, "") Local $aResult[UBound($aArray)][2], $iStart = 1 For $i = 0 To UBound($aArray) - 1 $aResult[$i][0] = $aArray[$i] $aResult[$i][1] = StringInStr($sMyString, $sDelim1 & $aResult[$i][0] & $sDelim2, 0, 1, $iStart) + 1 $iStart = $aResult[$i][1] Next Return $aResult EndFunc ;==>_StringBetweenAndPos edit new listing debugged Edited January 28, 2015 by Chimp JohnOne 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
JohnOne Posted January 28, 2015 Author Share Posted January 28, 2015 Ace that Chimp AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Gianni Posted January 28, 2015 Share Posted January 28, 2015 So far I have my _StringsInStr func It will be mutilated to _StringBetweenEx soon, so I'll put it here for posterity. #cs $Array = _StringsInStr("The mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad land", "mad") If Not IsArray($Array) Then Exit MsgBox(0, 0, 0) EndIf _ArrayDisplay($Array) #ce Func _StringsInStr($SearchIn, $SearchFor) Local $Size = 10 Local $aPos[$Size], $Found = 0, $Index = 0 Do $Found = StringInStr($SearchIn, $SearchFor, 0, 1, $Found + 1) If $Found Then If $Index = $Size Then $Size += $Size ReDim $aPos[$Size] EndIf $aPos[$Index] = $Found $Index += 1 EndIf Until $Found = 0 Or @error If $Index = 0 Then Return SetError(1, 0, 0) EndIf ReDim $aPos[$Index] Return $aPos EndFunc ;==>_StringsInStr your function a bit semplified .... by using StringReplace($SearchIn, $SearchFor, $SearchFor) and then reading @extended, you know the nr. of occurrences of searched string... #include <Array.au3> $Array = _StringsInStr("The mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad land", "mad") If Not IsArray($Array) Then Exit MsgBox(0, 0, 0) EndIf _ArrayDisplay($Array) Func _StringsInStr($SearchIn, $SearchFor) StringReplace($SearchIn, $SearchFor, $SearchFor) $iOccurrences = @extended If Not $iOccurrences Then Return SetError(1, 0, "") Local $aPos[$iOccurrences] For $i = 1 To $iOccurrences $aPos[$i - 1] = StringInStr($SearchIn, $SearchFor, 0, $i) Next Return $aPos EndFunc ;==>_StringsInStr JohnOne 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
bogQ Posted January 28, 2015 Share Posted January 28, 2015 (edited) maybe its semplified but yout preformance isnt good, another way around expandcollapse popup#include <Array.au3> $loops = 1000 $str = "The mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad land" $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr1($str, "mad");John Next $time = TimerDiff($in) ConsoleWrite($time & " John" & @CRLF) _ArrayDisplay($Array, $time) $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr2($str, "mad");bogQ Next $time = TimerDiff($in) ConsoleWrite($time & " bogQ" & @CRLF) _ArrayDisplay($Array, $time) $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr3($str, "mad");Chimp Next $time = TimerDiff($in) ConsoleWrite($time & " Chimp" & @CRLF) _ArrayDisplay($Array, $time) Func _StringsInStr1($SearchIn, $SearchFor) Local $Size = 10 Local $aPos[$Size], $Found = 0, $Index = 0 Do $Found = StringInStr($SearchIn, $SearchFor, 0, 1, $Found + 1) If $Found Then If $Index = $Size Then $Size += $Size ReDim $aPos[$Size] EndIf $aPos[$Index] = $Found $Index += 1 EndIf Until $Found = 0 Or @error If $Index = 0 Then Return SetError(1, 0, 0) EndIf ReDim $aPos[$Index] Return $aPos EndFunc ;==>_StringsInStr1 Func _StringsInStr2($SearchIn, $SearchFor) Local $aArray = StringSplit($SearchIn, $SearchFor, 1) If @error Then Return SetError(1, 0, 0) Local $sLen = StringLen($SearchFor) ReDim $aArray[$aArray[0]];remove last unneeded split $aArray[0] -= 1;Correct the number of returned values $aArray[1] = StringLen($aArray[1]) + 1;Calculate only first element with +1 coz other elements are calculated upon this element For $x = 2 To $aArray[0] $aArray[$x] = StringLen($aArray[$x]) + $aArray[$x - 1] + $sLen Next Return $aArray EndFunc ;==>_StringsInStr2 Func _StringsInStr3($SearchIn, $SearchFor) StringReplace($SearchIn, $SearchFor, $SearchFor) $iOccurrences = @extended If Not $iOccurrences Then Return SetError(1, 0, "") Local $aPos[$iOccurrences] For $i = 1 To $iOccurrences $aPos[$i - 1] = StringInStr($SearchIn, $SearchFor, 0, $i) Next Return $aPos EndFunc ;==>_StringsInStr3edit: small count of ellements correction Edited January 28, 2015 by bogQ JohnOne 1 TCP server and client - Learning about TCP servers and clients connectionAu3 oIrrlicht - Irrlicht projectAu3impact - Another 3D DLL game engine for autoit. (3impact 3Drad related) There are those that believe that the perfect heist lies in the preparation.Some say that it’s all in the timing, seizing the right opportunity. Others even say it’s the ability to leave no trace behind, be a ghost. Link to comment Share on other sites More sharing options...
Gianni Posted January 29, 2015 Share Posted January 29, 2015 (edited) maybe its semplified but yout preformance isnt good, another way around <snip> a bit improved my performances... but still a liitle slower than your expandcollapse popup#include <Array.au3> $loops = 1000 $str = "The mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad landThe mad mad mad mad the mad cat on mad day in mad dog ate mad mad mad the mad cat on mad day in mad land" $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr1($str, "mad");John Next $time = TimerDiff($in) ConsoleWrite($time & " John" & @CRLF) _ArrayDisplay($Array, $time) $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr2($str, "mad");bogQ Next $time = TimerDiff($in) ConsoleWrite($time & " bogQ" & @CRLF) _ArrayDisplay($Array, $time) $in = TimerInit() For $x = 1 To $loops $Array = _StringsInStr3($str, "mad");Chimp Next $time = TimerDiff($in) ConsoleWrite($time & " Chimp" & @CRLF) _ArrayDisplay($Array, $time) Func _StringsInStr1($SearchIn, $SearchFor) Local $Size = 10 Local $aPos[$Size], $Found = 0, $Index = 0 Do $Found = StringInStr($SearchIn, $SearchFor, 0, 1, $Found + 1) If $Found Then If $Index = $Size Then $Size += $Size ReDim $aPos[$Size] EndIf $aPos[$Index] = $Found $Index += 1 EndIf Until $Found = 0 Or @error If $Index = 0 Then Return SetError(1, 0, 0) EndIf ReDim $aPos[$Index] Return $aPos EndFunc ;==>_StringsInStr1 Func _StringsInStr2($SearchIn, $SearchFor) Local $aArray = StringSplit($SearchIn, $SearchFor, 1) If @error Then Return SetError(1, 0, 0) Local $sLen = StringLen($SearchFor) ReDim $aArray[$aArray[0]];remove last unneeded split $aArray[0] -= 1;Correct the number of returned values $aArray[1] = StringLen($aArray[1]) + 1;Calculate only first element with +1 coz other elements are calculated upon this element For $x = 2 To $aArray[0] $aArray[$x] = StringLen($aArray[$x]) + $aArray[$x - 1] + $sLen Next Return $aArray EndFunc ;==>_StringsInStr2 Func _StringsInStr3($SearchIn, $SearchFor) StringReplace($SearchIn, $SearchFor, $SearchFor) $iOccurrences = @extended If Not $iOccurrences Then Return SetError(1, 0, "") Local $iSearchLen = StringLen($SearchFor), $aPos[$iOccurrences + 1] = [1 - $iSearchLen] For $i = 1 To $iOccurrences $aPos[$i] = StringInStr($SearchIn, $SearchFor, 2, 1, $aPos[$i - 1] + $iSearchLen) Next $aPos[0] = $iOccurrences Return $aPos EndFunc ;==>_StringsInStr3 edit: little debug Edited January 29, 2015 by Chimp JohnOne 1 Chimp small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt.... Link to comment Share on other sites More sharing options...
JohnOne Posted January 29, 2015 Author Share Posted January 29, 2015 What happened to my _StringBetweenEX func. I'd swear on my new kidney I posted it here last night. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted January 29, 2015 Author Share Posted January 29, 2015 Well, no, I just found it with the post button unpressed on my other computer, duh! Here's what I came up with. expandcollapse popup#cs $Array = _StringBetweenEX("[my]zero[strings]hello[to]example[find]one[in]two[brackets]", "[", "]") If Not IsArray($Array) Then Exit MsgBox(0, 0, 0) EndIf _ArrayDisplay($Array) #ce Func _StringBetweenEX($SearchIn, $sStart, $sEnd) Local $Size = 10 Local $aPos[$Size][3], $Found = 0, $Found2 = 0, $Index = 0 Do $Found = StringInStr($SearchIn, $sStart, 0, 1, $Found + 1) If $Found Then $Found2 = StringInStr($SearchIn, $sEnd, 0, 1, $Found + 1) EndIf If $Found And $Found2 Then If $Index = $Size Then $Size += $Size ReDim $aPos[$Size][3] EndIf $aPos[$Index][0] = StringMid($SearchIn, $Found + 1, $Found2 - ($Found + 1)) $aPos[$Index][1] = $Found $aPos[$Index][2] = $Found2 $Index += 1 EndIf Until $Found = 0 Or @error If $Index = 0 Then Return SetError(1, 0, 0) EndIf ReDim $aPos[$Index][3] Return $aPos EndFunc ;==>_StringBetweenEX AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted January 29, 2015 Author Share Posted January 29, 2015 And thanks for the replies and input men, I appreciate it. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SadBunny Posted January 29, 2015 Share Posted January 29, 2015 Hmmz, if only this could be done somewhat reliably with occurances of capture groups in regex matches over a string instead of substrings between fixed delimiters... expandcollapse popup#include <Array.au3> ; 0 0 0 0 0 ; 123456789 123456789 123456789 123456789 123456789 $stringy = "I 1want to2 (this --> w <-- should not be counted," ; 1-50 $stringy = $stringy & " this --> 1 w 1 <-- should) know 3things4 about al" ; 51-100 $stringy = $stringy & "l 5strings67 beween digits8. This --> 12 <-- shoul" ; 101-150 $stringy = $stringy & "d lead to an empty string which cannot be indicate" ; 151-200 $stringy = $stringy & "d by a string position (it should lead to 0,0). 9 " ; 201-250 $stringy = $stringy & "This sentence should show up.10 This shouldn't...." ; 251-300 _ArrayDisplay(_stringRegExpWithPositions($stringy, "[0-9](.*?)[0-9]")) Exit Func _stringRegExpWithPositions($searchIn, $regex) ; remember the initial regex array and the count of found items; we'll need that later. If nothing found, just return False. $aFound = StringRegExp($searchIn, $regex, 3) $aFoundCount = UBound($aFound) If @error Then Return False Dim $result[0][3] ; We're going to work through the $searchIn, hunting the strings that matched the regex to find out their positions. $iIndex = 0 For $i In $aFound If $i == "" Then ; Can't indicate the position of an empty string in a string, since all positions in a string have a non-empty char. ; Add the element ("") to the array with positions 0,0 Local $newItem[1][3] = [["", 0, 0]] Else ; Ok, we got something of which we can find the position. Do ; We need to make sure that the regex-match that we found doesn't happen to occur earlier in the string too ; For instance, "x1x1" has one match for "[0-9](.*?)[0-9]". The captured group we want is on pos 3, but "x" is found at pos 1 too. ; To be safe, we compare whether the regex match actually changes when we cut out the current occurance of the substring. $iIndex = StringInStr($searchIn, $i, 0, 1, $iIndex + 1) $iLength = StringLen($i) $testString = StringLeft($searchIn, $iIndex - 1) & StringMid($searchIn, $iIndex + $iLength) Until Not _isArrayEqual(StringRegExp($searchIn, $regex, 3), StringRegExp($testString, $regex, 3)) ; Add the found substring and the starting and ending positions to our result array. Local $newItem[1][3] = [[$i, $iIndex, $iIndex + StringLen($i) - 1]] ; Local $newItem[1][3] = [[$i, $iIndex, StringLen($i)]] or, more insteresting to me personally, starting position and length... EndIf _ArrayAdd($result, $newItem) Next Return $result EndFunc ;==>_stringRegExpWithPositions Func _isArrayEqual($a1, $a2) ; compares only 1d arrays of the same size If Not IsArray($a1) Or Not IsArray($a2) Or UBound($a1) <> UBound($a2) Or UBound($a1, 2) <> 0 Then Return False For $i = 0 To UBound($a1) - 1 If $a1[$i] <> $a2[$i] Then Return False Next Return True EndFunc ;==>_isArrayEqual Pretty nifty if I do say so myself Turns out it even works pretty well for nested capture groups (like "[0-9]((.*?) .*?)[0-9]"). JohnOne 1 Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
UEZ Posted January 29, 2015 Share Posted January 29, 2015 (edited) Here my idea:#include <Array.au3> ; 1234567890123456789012345678901234567890123456789012345678901234567890 $sText = "[#my#]zero[#strings#]hello[#to#]example[#find#]one[#in#]two[#brackets#]" $aResult = _StringGetPosEx($sText, "[#", "#]") _ArrayDisplay($aResult) Func _StringGetPosEx($sString, $sStart, $sEnd, $bCase = False) StringReplace($sString, $sStart, $sStart) Local $iStarts = @extended StringReplace($sString, $sEnd, $sEnd) Local $iEnds = @extended, $iLenL = StringLen($sStart), $iLenR = StringLen($sEnd) Local $aPosStarts[$iStarts], $aPosEnds[$iEnds], $i, $iMin $iMin = UBound($aPosStarts) < UBound($aPosEnds) ? UBound($aPosStarts) : UBound($aPosEnds) For $i = 0 To $iMin - 1 $aPosStarts[$i] = StringInStr($sString, $sStart, $bCase, $i + 1, 1) $aPosEnds[$i] = StringInStr($sString, $sEnd, $bCase, $i + 1, 1) Next Local $aResult[$iMin][3] For $i = 0 To UBound($aResult) - 1 $aResult[$i][0] = StringMid($sString, $aPosStarts[$i] + $iLenL, $aPosEnds[$i] - $aPosStarts[$i] - $iLenR) $aResult[$i][1] = $aPosStarts[$i] + $iLenL $aResult[$i][2] = $aPosEnds[$i] - 1 Next Return $aResult EndFuncWorks for this particular simple example with the brackets, might not for other constellations (not tested).Br,UEZ Edited January 30, 2015 by UEZ JohnOne 1 Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
bogQ Posted January 29, 2015 Share Posted January 29, 2015 (edited) I just don't know where do you find this brain teasers JohnOne... my try to wrap my head around this one resulted in this, and i'm not even sure if its working correctly or how it preform, and is it even doing what it need to do, but it was a fun try and im off no sleep now... #include <Array.au3> $var = "aha [amy aa] zero [a strings a] hello [am to a] example[afinda]onea[aina]two[abracketsbracketa]afterbrackettt [aa]" ;~ $var = "[][my]zero[strings]hello[to]example[find]one[in]two[brackets]" ;~ $var = "aha [amy aa]" ;~ $var = "" $Array = _PosFrombetween($var, '[a', 'a]') ;~ $Array = _PosFrombetween($var, '[', ']') _ArrayDisplay($Array) Func _PosFrombetween($var, $start, $end) Local $verb = "(.*?)(\Q" & $start & "\E)(.*?)(\Q" & $end & "\E)";edited from some udf Local $arr = StringRegExp($var, $verb, 3) If Not IsArray($arr) Then Return SetError(1, 0, 0) _ArrayDisplay($arr, 'words');comment out this line if needed, it's here only for testing purpose Local $Array[(UBound($arr) / 4)][4] For $x = 2 To UBound($arr) - 1 Step 4 $Array[(($x + 2) / 4) - 1][0] = '"' & $arr[$x] & '"' Select Case $x <> 2 $Array[(($x + 2) / 4) - 1][1] = StringLen($arr[$x - 3]) + StringLen($arr[$x - 2]) + StringLen($arr[$x - 1]) + $Array[((($x + 2) / 4) - 1) - 1][3] Case Else $Array[(($x + 2) / 4) - 1][1] = StringLen($arr[$x - 2]) + StringLen($arr[$x - 1]) EndSelect $Array[(($x + 2) / 4) - 1][2] = StringLen($arr[$x]) $Array[(($x + 2) / 4) - 1][3] = $Array[(($x + 2) / 4) - 1][1] + $Array[(($x + 2) / 4) - 1][2] Next Return $Array EndFunc ;==>_PosFrombetween Edited January 30, 2015 by bogQ JohnOne 1 TCP server and client - Learning about TCP servers and clients connectionAu3 oIrrlicht - Irrlicht projectAu3impact - Another 3D DLL game engine for autoit. (3impact 3Drad related) There are those that believe that the perfect heist lies in the preparation.Some say that it’s all in the timing, seizing the right opportunity. Others even say it’s the ability to leave no trace behind, be a ghost. Link to comment Share on other sites More sharing options...
jaberwacky Posted January 29, 2015 Share Posted January 29, 2015 also to return the positions of any strings found. I thought _StringBetween did this already. JohnOne 1 Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
JohnOne Posted January 30, 2015 Author Share Posted January 30, 2015 If it does, then I'll eat my mouse. czardas 1 AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
JohnOne Posted January 30, 2015 Author Share Posted January 30, 2015 Hmmz, if only this could be done somewhat reliably with occurances of capture groups in regex matches over a string instead of substrings between fixed delimiters... expandcollapse popup#include <Array.au3> ; 0 0 0 0 0 ; 123456789 123456789 123456789 123456789 123456789 $stringy = "I 1want to2 (this --> w <-- should not be counted," ; 1-50 $stringy = $stringy & " this --> 1 w 1 <-- should) know 3things4 about al" ; 51-100 $stringy = $stringy & "l 5strings67 beween digits8. This --> 12 <-- shoul" ; 101-150 $stringy = $stringy & "d lead to an empty string which cannot be indicate" ; 151-200 $stringy = $stringy & "d by a string position (it should lead to 0,0). 9 " ; 201-250 $stringy = $stringy & "This sentence should show up.10 This shouldn't...." ; 251-300 _ArrayDisplay(_stringRegExpWithPositions($stringy, "[0-9](.*?)[0-9]")) Exit Func _stringRegExpWithPositions($searchIn, $regex) ; remember the initial regex array and the count of found items; we'll need that later. If nothing found, just return False. $aFound = StringRegExp($searchIn, $regex, 3) $aFoundCount = UBound($aFound) If @error Then Return False Dim $result[0][3] ; We're going to work through the $searchIn, hunting the strings that matched the regex to find out their positions. $iIndex = 0 For $i In $aFound If $i == "" Then ; Can't indicate the position of an empty string in a string, since all positions in a string have a non-empty char. ; Add the element ("") to the array with positions 0,0 Local $newItem[1][3] = [["", 0, 0]] Else ; Ok, we got something of which we can find the position. Do ; We need to make sure that the regex-match that we found doesn't happen to occur earlier in the string too ; For instance, "x1x1" has one match for "[0-9](.*?)[0-9]". The captured group we want is on pos 3, but "x" is found at pos 1 too. ; To be safe, we compare whether the regex match actually changes when we cut out the current occurance of the substring. $iIndex = StringInStr($searchIn, $i, 0, 1, $iIndex + 1) $iLength = StringLen($i) $testString = StringLeft($searchIn, $iIndex - 1) & StringMid($searchIn, $iIndex + $iLength) Until Not _isArrayEqual(StringRegExp($searchIn, $regex, 3), StringRegExp($testString, $regex, 3)) ; Add the found substring and the starting and ending positions to our result array. Local $newItem[1][3] = [[$i, $iIndex, $iIndex + StringLen($i) - 1]] ; Local $newItem[1][3] = [[$i, $iIndex, StringLen($i)]] or, more insteresting to me personally, starting position and length... EndIf _ArrayAdd($result, $newItem) Next Return $result EndFunc ;==>_stringRegExpWithPositions Func _isArrayEqual($a1, $a2) ; compares only 1d arrays of the same size If Not IsArray($a1) Or Not IsArray($a2) Or UBound($a1) <> UBound($a2) Or UBound($a1, 2) <> 0 Then Return False For $i = 0 To UBound($a1) - 1 If $a1[$i] <> $a2[$i] Then Return False Next Return True EndFunc ;==>_isArrayEqual Pretty nifty if I do say so myself Turns out it even works pretty well for nested capture groups (like "[0-9]((.*?) .*?)[0-9]"). That is beautiful. It's a script and it's a book AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
SadBunny Posted January 30, 2015 Share Posted January 30, 2015 (edited) That is beautiful. It's a script and it's a book Thanks... And yes, my colleagues gave me the strikingly applicable nickname "-vvvv". /edit: by the way... The thing is that if you cut out all the comments, the function is too small to believe Edited January 30, 2015 by SadBunny Roses are FF0000, violets are 0000FF... All my base are belong to you. Link to comment Share on other sites More sharing options...
JohnOne Posted January 30, 2015 Author Share Posted January 30, 2015 You've been registered her for nearly 10 years, nice to meet you. I hope you don't mind, but I'm going to start reading your posts. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now