Jump to content

Recommended Posts

Posted

Hi

I have ask some time ago a similar question but i think i have used a wrong method.

My idea was adding a pipe between word, then split the | and every single char. But is better to post directly the script

#include <Array.au3>

Global $aString

Add2DEntry("ABC[123CDE]")
Add2DEntry("ABCD[DEF]")
Add2DEntry("ABCD[H1]EFG")
Add2DEntry("ABC")

_ArrayDisplay($aString)

Func Add2DEntry($sAdd2DEntry)
    If Not IsDeclared("$sString") Then Global $sString
    If StringRight($sAdd2DEntry, 1) <> "|" Then $sAdd2DEntry = $sAdd2DEntry & "|"
    $sString &= $sAdd2DEntry
    Local $aSplit_1 = StringSplit(StringTrimRight($sString, 1), "|", 1)
    Global $aString[1][$aSplit_1[0]], $iNum = 0
    For $i = 1 To $aSplit_1[0]
        $sLine = $aSplit_1[$i]
        $iLen = StringLen($sLine)
        Local $aSplit_2[$iLen + 1]
        $iWriteindex = 0
        For $iReadIndex = 1 To $iLen
            $sChar = StringMid($sLine, $iReadIndex, 1)
            $aSplit_2[$iWriteindex] = $sChar
            If $sChar = "[" Then
                Do
                    $iReadIndex += 1
                    $sChar = StringMid($sLine, $iReadIndex, 1)
                    $aSplit_2[$iWriteindex] &= $sChar
                Until $sChar = "]"
            EndIf
            ConsoleWrite($aSplit_2[$iWriteindex] & @CR) ; <<<<<<<<<<<<<<< so many re-declare!
            $iWriteindex += 1
        Next
        If UBound($aString) < $iWriteindex Then
            ReDim $aString[$iWriteindex][$aSplit_1[0]]
        EndIf
        For $j = 0 To $iWriteindex - 1
            $aString[$j][$i - 1] = $aSplit_2[$j]
        Next
    Next
EndFunc   ;==>Add2DEntry

The result of _ArrayDisplay is correct but i see in the ConsoleWrite the Function is not very "clean", for my mistake. So is possible to "improve" the function and having the same result of _ArrayDisplay?

Thanks again

Posted

This example adds the array from the regular expression to the 2D array.

#include <Array.au3>

Global $aArray2D[0][0]

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; Increment number of columns
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    ReDim $aArray[$iMaxRows][$Col]
    For $Row = 0 To UBound($aTemp) - 1
        $aArray[$Row][$Col - 1] = $aTemp[$Row]
    Next
EndFunc   ;==>Add2DEntry
Posted (edited)

Malkey,

First thanks for your help. I have a couple of problem because your code is a bit different ( and short ) respect of the one of the first post ;)

In first place i can't declare empty array, i'm using the old stable and for now is complicated to update to last stable:

Global $aArray2D[0][0]

I have resolved this part declaring an 1D array, will be converted in 2D inside the _Add2DEntry and the ReDim part

Global $aArray2D[1]

The second one and most important, you use RegEx for the string inside the [ ] insted of looping like mine with Do...Until ( If $sChar = "[" Then Do...Until $sChar = "]" )

So i have another "rules" to apply...i have a character set:

£$?&

If one or more of that charset is followed by a char ( only the first one ) take it to a single row like the [ ]

Example:

ABC[123CDE]$a --> take $a to a single row

ABC$?1EFG[123CDE] --> take $?1 to single row

and so on.

If one of more of that charset is not followed by a char ( like at the end of the string ) remove it/skip it

Example:

ABC[123CDE]$ --> result is ABC[123CDE]

If is followed by [ put everything on a single row:

ABC&?[123CDE] ---> result is &?[123CDE]

Thanks. I'm sorry for not put this part on the first post but I did not think your code would have been different from that ;)

P.S. [ ] without any char inside it is an invalid entry so i can't add it to the final array, i'm using StringReplace on $sAdd2DEntry for that. I don't know if is possible to remove it if no char between/extract the char between [...] using only one RegExp without make 2 different pass. If not isn't a problem, i'll use StringReplace.

Edited by johnmcloud
Posted (edited)

Malkey,

I have make the regexp for the things i have say in the previus post:

StringRegExp($sAdd2DEntry, "([£$?&]+(?:\[.*?\]|[^\s£$?&]))", 3)

Hope is correct. If you can make one fuction for everything i'm grateful. Have a nice day

Edited by johnmcloud
Posted (edited)

Here's hoping this example will work on an older version of AutoIt.

The Static variable declaration has been around for for a while.   We will see.

#include <Array.au3>

Global $aArray2D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
    Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col += 1 ; Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2") ; Remove unwanted characters - £$?& followed by [ or end of string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|[£\$?&]+.|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    If $Col = 1 Then
        $aArray = $aTemp
    ElseIf $Col = 2 Then ; 1D to 2D array
        Local $aTemp2 = $aArray ; Changing dimensions with ReDim erases contents of array.
        ReDim $aArray[$iMaxRows][2]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp2) Then $aArray[$Row][0] = $aTemp2[$Row]
            If $Row < UBound($aTemp) Then $aArray[$Row][1] = $aTemp[$Row]
        Next
    Else
        ReDim $aArray[$iMaxRows][$Col]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
        Next
    EndIf
EndFunc   ;==>Add2DEntry
Edited by Malkey
Posted (edited)

Work but also the previus one work with some changes, from your last script:

#include <Array.au3>

Global $aArray2D[1] ; <<<<<<<<<<<<<<<<<<<<<< 1D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)


Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
;~  Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; <<<<<<<<<<<<<<<<< Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2") ; Remove unwanted characters - £$?& followed by [ or end of string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "(\[.*?\]|[£\$?&]+.|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
;~     If $Col = 1 Then
;~         $aArray = $aTemp
;~     ElseIf $Col = 2 Then ; 1D to 2D array
;~         Local $aTemp2 = $aArray ; Changing dimensions with ReDim erases contents of array.
;~         ReDim $aArray[$iMaxRows][2]
;~         For $Row = 0 To $iMaxRows - 1
;~             If $Row < UBound($aTemp2) Then $aArray[$Row][0] = $aTemp2[$Row]
;~             If $Row < UBound($aTemp) Then $aArray[$Row][1] = $aTemp[$Row]
;~         Next
;~     Else
        ReDim $aArray[$iMaxRows][$Col]
        For $Row = 0 To $iMaxRows - 1
            If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
        Next
;~     EndIf
EndFunc   ;==>Add2DEntry

I have commented "unecessary" code and change the first array variable and $Col. I think the result is the same ;)

With the last script there is a problem with this entry:

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

Both give me the same result but are different ( see my regexp )

The first is:

A

B

C

[123CDE]

The second need to be:

A

B

C

&?[123CDE]

From my post:

If one of more of that charset is not followed by a char ( like at the end of the string ) remove it/skip it

Example:

ABC[123CDE]$ --> result is ABC[123CDE]

If is followed by [ put everything on a single row:

ABC&?[123CDE] ---> result is &?[123CDE]

Thanks ;)

Edited by johnmcloud
  • Moderators
Posted

This line removes all "unwanted" characters:

StringRegExpReplace($sAdd2DEntry, "([£\$?&]+)(\[|$)", "\2")

Are you saying they are NOT unwanted characters?

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted (edited)

They are "wanted" character if:

a ) Is followed by a char, so take only the fist one match, so return $a or $?1 ( Done )

b ) Is followed by a [ so take the entire match, like $[ABC]

They are "unwanted" char if:

c ) They are not followed by a char, like at the end of the string [ABC]% ( Done )

That regexp only remove the unwanted char but i need something also for point b ) maybe can be done in the same regexp that split the character between square --> "([.*?]|[£$?&]+.|.)"

Edited by johnmcloud
  • Moderators
Posted

You're getting closer to be descriptive.  But a "char" is any character (decimal 0 - 255 for just the Ascii table alone).

You have all these rules, but it's difficult to follow (I'm only guessing english is not your native tongue).

Provide a list of all scenarios, then provide the output you'd expect from them.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted (edited)

The last script posted by Malkey follow all the rules except the one i have descripted at point b )

Add2DEntry($aArray2D, "ABC&?[123CDE]")

Expecetd result is:

A

B

C

&?[123CDE]

Actually is:

A

B

C

[123CDE]

The charset is always the same ( £$?& ) can be one of more of that previus the [ 

All the rest is already covered by the two regexp. Yes english is not my mother languages, i'll try to make the best :D

Edited by johnmcloud
  • Moderators
Posted

Again...

StringRegExpReplace($sAdd2DEntry, "([£$?&]+)([|$)", "2")

Makes it impossible to get your request.  It replaces all those special characters before the square bracket.  Try removing that line of code entirely.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted (edited)

I don't need to "replaces all those special characters before the square bracket" but only if the "special characters" is not followed by a char, like at the end of the string. Example:

ABC[123CDE]&? become ABC[123CDE]

If i remove the line the result is:

A

B

C

&?[

1

2

3

C

D

E

]

Edited by johnmcloud
  • Moderators
Posted

So...

$sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+$)", "") ; remove unwanted characters only at the end of the string.
Local $aTemp = StringRegExp($sAdd2DEntry, "([£\$?&]*\[.*?\]|.)", 3)

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted (edited)

Your version work for point b ) but break the point a ) ( that was included in regexp of Malkey, try it out ) from post #8 :(

Add2DEntry($aArray2D, "ABC[123CDE]$a")

Expected result:

A

B

C

[CDE]

$a

Actual result:

A

B

C

[CDE]

$

a

Add2DEntry($aArray2D, "ABC?$1EFG[123CDE]")

Expected result:

A

B

C

?$1

E

F

G

[123CDE]

Edited by johnmcloud
  • Moderators
Posted

So many rules...

#include <Array.au3>

Global $aArray2D[1] ; <<<<<<<<<<<<<<<<<<<<<< 1D

Add2DEntry($aArray2D, "ABC[123CDE]")
Add2DEntry($aArray2D, "[AB]CD[][E][FG]H")
Add2DEntry($aArray2D, "ABCD[H1]EFG")
Add2DEntry($aArray2D, "ABC")
Add2DEntry($aArray2D, "ABC[123CDE]$a")
Add2DEntry($aArray2D, "ABC$?1EFG[123CDE]")
Add2DEntry($aArray2D, "ABC[123CDE]$")
Add2DEntry($aArray2D, "ABC&?[123CDE]")

_ArrayDisplay($aArray2D)

Func Add2DEntry(ByRef $aArray, $sAdd2DEntry)
;~  Local Static $Col
    Local $iMaxRows = UBound($aArray)
    $Col = UBound($aArray, 2) + 1 ; <<<<<<<<<<<<<<<<< Increment number of columns
    $sAdd2DEntry = StringRegExpReplace($sAdd2DEntry, "([£\$?&]+$)", "") ; remove unwanted characters only at the end of the string.
    Local $aTemp = StringRegExp($sAdd2DEntry, "([£\$?&]*\[.*?\]|[£\$?&]+(?!\[).|.)", 3)
    If UBound($aTemp) > $iMaxRows Then $iMaxRows = UBound($aTemp)
    ReDim $aArray[$iMaxRows][$Col]
    For $Row = 0 To $iMaxRows - 1
        If $Row < UBound($aTemp) Then $aArray[$Row][$Col - 1] = $aTemp[$Row]
    Next
EndFunc   ;==>Add2DEntry

.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Posted

So many rules...

 

Tell me about it! :(

I'm sorry for these complications, an initial look everything looks correct but i'm still testing if cover all. Thanks

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
  • Recently Browsing   0 members

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