Jump to content

find the common text in 2 strings ?


Recommended Posts

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

Link to comment
Share on other sites

  • Moderators

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

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 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

 

Link to comment
Share on other sites

  • Moderators

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

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 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

 

Link to comment
Share on other sites

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

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

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.

Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...