Jump to content
Sign in to follow this  
Alexxander

find the common text in 2 strings ?

Recommended Posts

Alexxander

hello

how can i make Autoit find the common text in 2 strings ?

i have this

/storage/sdcard0/test/auto-import
/storage/sdcard0/test/projects

but it must be a back slash for every word

i mean 

/storage/sdcard0/test/auto-import1
/storage/sdcard0/test/auto-import2

this must only match" /storage/sdcard0/test/"

it must NOT be /storage/sdcard0/test/auto-import

i want Aautoit to give me "/storage/sdcard0/test/" as a result 

and how can i do this if i don't know the number of string i want it to compare ?

Edited by Alexxander

Share this post


Link to post
Share on other sites
Melba23

Alexxander,

No doubt an SRE guru will come up with a one-liner, but you can also do it like this: ;)

#include <MsgBoxConstants.au3>

Global $aTest_1[2] = ["/storage/sdcard0/test/auto-import", "/storage/sdcard0/test/projects"]

Global $aTest_2[2] = ["/storage/sdcard0/test/auto-import1", "/storage/sdcard0/test/auto-import2"]

MsgBox($MB_SYSTEMMODAL, "Common", _Extract_Common($aTest_1))

MsgBox($MB_SYSTEMMODAL, "Common", _Extract_Common($aTest_2))

Func _Extract_Common($aArray)

    ; Split strings
    $aSplit_0 = StringSplit($aArray[0], "/")
    $aSplit_1 = StringSplit($aArray[1], "/")
    ; Determine smallest array size
    $iLast = ( ($aSplit_0[0] > $aSplit_1[0]) ? ($aSplit_1[0]) : ($aSplit_0[0]) )
    ; Loop through arrays and compare elements
    $sCommon = ""
    For $i = 1 To $iLast
        If $aSplit_0[$i] == $aSplit_1[$i] Then
            ; Add to common string
            $sCommon &= $aSplit_0[$i] & "/"
        Else
            ; No point in looking further
            ExitLoop
        EndIf
    Next

    Return $sCommon

EndFunc
All clear? :)

M23

  • Like 1

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______Open Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
Alexxander

awesome Melba23

very nice work , but i aslo need the uncommon 

i'am making a simple file manager so i need the common to be the current root and the uncommon to make it the list in that root


Share this post


Link to post
Share on other sites
Melba23

Alexxander,

I have just seen your edit. To run this over a unknown number of strings you can do something like this:

#include <MsgBoxConstants.au3>
#include <Array.au3>

Global $aTest[3] = ["/storage/sdcard0/test/auto-import", "/storage/sdcard0/test/auto-import2", "/storage/sdcard0/fred"]

MsgBox($MB_SYSTEMMODAL, "Common", _Extract_Common($aTest))

Func _Extract_Common($aArray)

    Local $aCommon = StringSplit($aArray[0], "/")

    For $i = 0 To UBound($aArray) - 1
        ; Split next string
        $aSplit = StringSplit($aArray[$i], "/")
        ; Determine smallest array size
        $iLast = ( ($aCommon[0] < $aSplit[0]) ? ($aCommon[0]) : ($aSplit[0]) )
        ; Loop through arrays and compare elements
        $sCommon = ""
        For $j = 1 To $iLast
            If $aSplit[$j] <> $aCommon[$j] Then
                ; ReDim common array and reset count
                ReDim $aCommon[$j]
                $aCommon[0] = $j - 1
                ExitLoop
            EndIf
        Next

    Next

    Return _ArrayToString($aCommon, "/", 1) & "/"

EndFunc
I hope that does the trick. :)

M23

Edited by Melba23
Removed some errorchecking code
  • Like 1

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______Open Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
UEZ

Here my version:

$sString =  "/storage/sdcard0/test/auto-import" & @CRLF & _
            "/storage/sdcard0/test/projects" & @CRLF & _
            "/storage/sdcard0/test/auto-import1" & @CRLF & _
            "/storage/sdcard0/test/auto-import2" & @CRLF & _
            "/storage/sdcard0/test2/auto-export"

MsgBox(0, "Test", FindCommonPath($sString))

Func FindCommonPath($sString)
    Local $a = StringSplitW($sString, "/")
    ReDim $a[UBound($a)][UBound($a, 2) - 1] ;remove last row
    Local $i, $iY, $iX = UBound($a, 2) - 1, $bEqual = True, $sCommon = "/"
    Do
        For $iY = 0 To UBound($a) - 2
            If $a[$iY][$iX] <> $a[$iY + 1][$iX] Then
                $bEqual = False
                ExitLoop
            EndIf
        Next
        If $bEqual Then
            For $i = 1 To UBound($a, 2) - 1
                $sCommon &= $a[0][$i] & "/"
            Next
            $sCommon = StringTrimRight($sCommon, 1)
            ExitLoop
        EndIf
        If $iX > 1 Then
            ReDim $a[UBound($a)][UBound($a, 2) - 1]
            $iX = UBound($a, 2) - 1
            $bEqual = True
        Else
            ExitLoop
        EndIf
    Until False
    Return $sCommon
EndFunc


; #FUNCTION# ========================================================================================================================================
; Name .................:   StringSplitW()
; Description ..........:   Splits  a string into columns instead of rows as it is done by SplitString(), like a csv file to a 2d array ;-)
; Syntax ...............:   StringSplitW($sString, $sDelimiter, $iWidthLen)
; Parameters ...........:   $sString - string to split
;                           $sDelimiter - [optional] the delimter how to split the string
;                           $iWidthLen - [optional] length of the row (amount of columns - default is 256)
; Return values .......:    Success - 2d array
;                           Error 1 - either $sString or $delimter is not set
;                           Error 2 - array width exceeded
;                           Error 3 - error splitting string
;
; Version .............:    v0.96 build 2015-01-20 beta
; Author ..............:    UEZ
; Modified ............:
; Remarks .............:    RegEx take from http://stackoverflow.com/questions/4476812/regular-expressions-how-to-replace-a-character-within-quotes
; Related .............:    StringSplit, StringReplace, StringRegExpReplace, StringLen, StringStripCR
; ===================================================================================================================================================
Func StringSplitW($sString, $sDelimiter = ";", $sQuotationMark = '"', $sDummy = "¦", $iWidthLen = 256)
    If $sString = "" Or $sDelimiter = "" Then Return SetError(1, 0, 0)
    Local $chk, $iWidth, $i, $j, $k, $iLen, $iMax = 1, $iMaxWidth
    Local $aPos[1], $l = 0
    Local $aSplit =  StringSplit(StringStripCR($sString), @LF)
    If @error Then Return SetError(3, 0, 0)
    Local $aVertical[$aSplit[0]][$iWidthLen], $iDelimiterLen = StringLen($sDelimiter) - 1, $sLine
    For $k = 1 To $aSplit[0]
        $iLen = StringLen($aSplit[$k])
        If $iLen > 1 Then
            $sLine = StringRegExpReplace($aSplit[$k], '(?m)\' & $sDelimiter & '(?=[^' & $sQuotationMark & ']*' & $sQuotationMark & '(?:[^' & $sQuotationMark & '\r\n]*' & $sQuotationMark & '[^' & $sQuotationMark & ']*' & $sQuotationMark & ')*[^' & $sQuotationMark & '\r\n]*$)', $sDummy)
            $chk = StringReplace($sLine, $sDelimiter, $sDelimiter)
            $iWidth = @extended
            If $iWidth > $iWidthLen Then Return SetError(2, 0, 0)
            If $iWidth >= $iMax Then $iMax = $iWidth + 1
            Switch $iWidth
                Case 0
                    $aVertical[$l][0] = $sLine
                Case Else
                    Dim $aPos[$iWidth * 2 + 2]
                    $j = 1
                    $aPos[0] = 1
                    For $i = 0 To $iWidth - 1
                        $aPos[$j] = StringInStr($sLine, $sDelimiter, 0, $i + 1) - 1
                        $aPos[$j + 1] = $aPos[$j] + 2 + $iDelimiterLen
                        $j += 2
                    Next
                    $aPos[UBound($aPos) - 1] = StringLen($sLine)
                    $j = 0
                    For $i = 0 To UBound($aPos) - 1 Step 2
                        $aVertical[$l][$j] = StringMid(StringReplace($sLine, $sDummy, $sDelimiter), $aPos[$i], $aPos[$i + 1] - $aPos[$i] + 1)
                        $j += 1
                    Next
                EndSwitch
                $l += 1
        EndIf
    Next
    ReDim $aVertical[$l][$iMax]
    Return $aVertical
EndFunc

Br,

UEZ

Edited by UEZ
  • Like 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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites
somdcomputerguy

Here is my interpretation of what is wanted..

Local $sString1 = "/storage/sdcard0/test/auto-import", $sString2 = "/storage/sdcard0/test/projects/auto-import3/additional text/", _
      $aString1 = StringSplit($sString1, "/"), $aString2 = StringSplit($sString2, "/"), _
      $b = '/'

If UBound($aString1) = UBound($aString2) Then Local $c = UBound($aString1) - 1
If UBound($aString1) < UBound($aString2) Then Local $c = UBound($aString1) - 1
If UBound($aString1) > UBound($aString2) Then Local $c = UBound($aString2) - 1

For $a = 1 To $c
    If $aString1[$a] = $aString2[$a] Then $b &= $aString1[$a] & "/"
Next

ConsoleWrite(StringTrimLeft($b, 1) & @LF)
edit: If it matters I changed the code so it'll run correctly if String2 is of shorter or equal length to String1 Edited by somdcomputerguy

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Share this post


Link to post
Share on other sites
somdcomputerguy

I changed my code again, now it works better, again..

Local $sString1 = "/storage/sdcard0/test/auto-import", $sString2 = "/storage/sdcard0/test/what/ever", _
$aString1 = StringSplit($sString1, "/"), $aString2 = StringSplit($sString2, "/"), $b

If UBound($aString1) <= UBound($aString2) Then Local $c = UBound($aString1) - 1
If UBound($aString1) >= UBound($aString2) Then Local $c = UBound($aString2) - 1

For $a = 1 To $c
If $aString1[$a] = $aString2[$a] Then $b &= $aString1[$a] & "/"
If $aString1[$a] <> $aString2[$a] Then ExitLoop
Next

ConsoleWrite($b & @LF)
Edited by somdcomputerguy
  • Like 1

- Bruce /*somdcomputerguy */  If you change the way you look at things, the things you look at change.

Share this post


Link to post
Share on other sites
mikell

somdcomputerguy,

What if there is a lot of strings ?

Here is a regex way :)

#include <Array.au3>

$sString =  "/storage/sdcard0/test/auto-import" & @CRLF & _
            "/storage/sdcard0/test/projects" & @CRLF & _
            "/storage/sdcard0/test/auto-import1" & @CRLF & _
            "/storage/sdcard0/test/auto-import2" & @CRLF & _
            "/storage/sdcard0/test/auto-import3" & @CRLF & _
            "/storage/sdcard0/test2/abc/auto-export"

$lines = StringRegExp($sString, '(?m)(^\N+)\R?', 3)
$tmp = StringSplit($lines[0], "/")
Local $res1 = "/", $res2 = $sString
For $i = 2 to $tmp[0]
   $sString = StringRegExpReplace($sString, '(?m)^/?' & $tmp[$i] & '/', "")
   If @extended = UBound($lines) Then 
        $res1 &= $tmp[$i] & "/"
        $res2 = $sString
   EndIf
Next

; MsgBox(0, "common", $res1)
; MsgBox(0, "uncommon", $res2)

Local $array[UBound($lines)][2]
For $i = 0 to UBound($array)-1
   $array[$i][0] = $res1 
   $array[$i][1] = StringReplace($lines[$i], $res1, "")
Next
_ArrayDisplay($array)

Edit

an other funny one  :idiot:

#include <Array.au3>

$sString =  "/storage/sdcard0/test/" & @CRLF & _
            "/storage/sdcard0/test/test2/auto-import" & @CRLF & _
            "/storage/sdcard0/test/projects" & @CRLF & _
            "/storage/sdcard0/test/auto-import1" & @CRLF & _
            "/storage/sdcard0/test/auto-import2" & @CRLF & _
            "/storage/sdcard0/test/auto-import3" & @CRLF & _
            "/storage/sdcard0/test3/abc/auto-export"

$lines = StringRegExp($sString, '(?m)^(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?(?:/(.*?))?$', 4)
Local $res = "", $k = 1
While 1
   For $i = 1 to UBound($lines)-1   
      If ($lines[$i])[$k] <> ($lines[$i-1])[$k] Then Exitloop 2
   Next
   $res &= ($lines[0])[$k] & "/"
   $k += 1
Wend

; MsgBox(0, "common", $res)

Local $array[UBound($lines)][2]
For $i = 0 to UBound($array)-1
   $array[$i][0] = $res 
   $array[$i][1] = StringReplace(($lines[$i])[0], "/" & $res, "")
Next
_ArrayDisplay($array)
Edited by mikell

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  

×