[RESOLVED] Split Function Struggle!
Hi everyone,
Driving me crazy! I had done it for some one long time ago now I can't remember how and I don't have the code!
I have a text like this in a single text variable:
"1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4"
and so on, goes up to probably 60 numbers. (e.g. 60. Ba4 Kc2).
What I want to do is to get them separated in array, I know the syntax of Split function in vb6, but I don't know what condition to use as I couldn't find a chance with wild cards in vb6.
I eventually want to get it as:
1. Bc4 Na2
2. Ka8 Bc3
3. Bxe4 f2
4. Kc2 Qa4
....
It means using wild cards it would be like split(variable, "?.") as the question marks represents one single character (numeric value would be more precise!).
But there are apparently not actual wild cards in vb6.
I can not use the space condition because there are some more spaces that I dont want them to be breakpoints.
I can't use dots because it would become like this:
1
Bc4 Na2 2
Ka8 Bc3 3
...
(I know with a little manipulation one would correct the above one, but its a software that needs reliable coding not to get the string apart like this then stick it together again... doesn't feel correct).
In advance, thanks for ideas.
Re: Split Function Struggle!
Thread moved from the 'General Developer' forum (which is for things that aren't language specific) to the 'VB6' forum.
VB6 does have wildcards, but not as part of the Split function... and even if it did, it wouldn't help you much because Split removes the delimiters (so the numbers and dots would be removed), and 60 doesn't match ? (and ??? to allow 3 digits would give the wrong result for single digit numbers).
I can think of basically two types of method to achieve what you want.
The first is to use Split to separate items by the dots, and then for each item use InStrRev to find the last space (and thus start of the number) so you can move the number from each item to the next.
The other is to use InStr to find dots, and then use InStrRev from that point in the same manner as above. You will need to ReDim an array for the results tho, which will probably make it slower. You are also likely to need more code.
Re: Split Function Struggle!
See if this does it:
Code:
Dim Arr() As String
Dim i As Long
Arr = Split("1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4")
For i = 0 To UBound(Arr) Step 3
Debug.Print Arr(i + 1), Arr(i + 2) 'arr(i) is the numbers
Next
Re: Split Function Struggle!
Split will make it complex...
Here is one way to achieve what you want...
Code:
Option Explicit
Sub Sample()
Dim StrString As String
Dim MYArray() As String
Dim pos1 As Long, i As Long
StrString = "1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4"
pos1 = 1: i = 1
Do While pos1 <> 0
pos1 = InStr(4, StrString, ".")
If pos1 = 0 And Len(Trim(StrString)) <> 0 Then
ReDim Preserve MYArray(i)
MYArray(i) = StrString
Exit Do
End If
Do While Len(Trim(Mid(StrString, pos1, 1))) <> 0
pos1 = pos1 - 1
Loop
ReDim Preserve MYArray(i)
MYArray(i) = Mid(StrString, 1, pos1 - 1)
StrString = Replace(StrString, Mid(StrString, 1, pos1 - 1), "")
i = i + 1
Loop
For i = 1 To UBound(MYArray)
MsgBox MYArray(i)
Next i
End Sub
Sid
Re: Split Function Struggle!
You may be interested in the Chess Openings link in my signature, which has a fully functional PGN parser that you can look at.
Did you need to do anything with the move data, or just format it?
(Also, the dot is expressly used to separate moves, to the point that you're not supposed to use dots even in annotations.)
Re: Split Function Struggle!
There is always the Regular Expression option. For this example make sure you set a reference for "Microsoft VBScript Regular Expression 5.5"
Code:
Private Sub Command1_Click()
Dim strInput As String
Dim regEx As RegExp
Dim strArr() As String
Dim i As Integer
Dim regMatchCol As MatchCollection
Dim regMatch As Match
strInput = "1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4"
Set regEx = New RegExp
regEx.Global = True
regEx.Pattern = "\d*\.{1}\s{1}[a-zA-Z]{2,3}\d{1}\s{1}[a-zA-Z]{1,2}\d{1}"
Set regMatchCol = regEx.Execute(strInput)
If regMatchCol.Count > 0 Then
ReDim Preserve strArr(regMatchCol.Count - 1)
For Each regMatch In regMatchCol
strArr(i) = regMatch.Value
i = i + 1
Next regMatch
Debug.Print strInput
Debug.Print
For i = 0 To UBound(strArr)
Debug.Print strArr(i)
Next i
End If
End Sub
Re: Split Function Struggle!
A collection allows you to store the index as a key:
Code:
Dim C As Collection, L As Long, O As Long, P As Long, S As Long, T As String
' prepare a collection for our use
Set C = New Collection
' test string
T = "1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4"
Do
' find the dot separator
P = InStr(P + 1, T, ". ")
If P Then
' find a previous space (or the first character of string)
S = InStrRev(T, " ", P - 1) + 1
' L > 0 after first loop, store contents & key
If L Then C.Add Mid$(T, O + 2, S - O - 2), Mid$(T, L, O - L)
' remember last values
L = S: O = P
End If
Loop While P
' if anything found then store last item contents & key
If L Then C.Add Mid$(T, O + 2), Mid$(T, L, O - L)
' test numeric indexes
Debug.Print "Indexes:"
For L = 1 To C.Count: Debug.Print L, C(L): Next
' test string keys
Debug.Print "Keys:"
Debug.Print C("1"), C("2"), C("3"), C("4")
The advantage of the key is that you will see the keys giving you the order you are expecting if you change the string to something like T = "2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4 1. Bc4 Na2" – probably not the most useful feature, but this may work in other generic parser requirements people may have so it is included in this code.
Why do I write code that does more than asked?
Answer: because I'm a bad, inefficient programmer.
Re: Split Function Struggle!
Wow, Lots of answers in a single day, thank you guys and sorry for late reply. Had some problems with connecting to the Internet.
si_the_geek,
Quote:
... and even if it did, it wouldn't help you much because Split removes the delimiters
Yes, you are right, I faced this problem. I will try the two methods you have mentioned. The matter is that I didn't want to get deep into manipulating strings, as the example I given already, is a one line from a big chess database that could vary in 3 or 4 different formats, so if i use string manipulations it may work with one format correctly but mess the others.
I will tell you once I try your methods, thank you so much.
---------
VBClassicRocks,
Thanks. I will try your method, but I don't see what
Split("1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4")
does actually, I should try it. Thanks.
---------
koolsid,
Thanks, it seems I can get the logic. I should give it a try.
--------
Ellis Dee,
You got me there! Yes, it's a PGN reader and I already opened you code, I should be able to get lots of help out of it.
Actually I am a member of a big Artificial Intelligence Chess Program.
My software does every think in chess and it needs to be ready for testing.
I had a PGN Reader already that was not so reliable as I said earlier, because as you know there are 2-3 different formats of writing PGN files.
My program does as the standard international format but should be able to read all.
Thank you, I am going to read your code and test it with other PGN formats.
----------
MarkT,
Thank you, I am not familiar with the Microsoft VBScript Regular Expression 5.5 and should read it's instruction first to see what it does.
Then I will implement your code to see the result. (You have put lots of effort apparently! Sincerely!).
----------
Merri,
Thank you, I have to read some stuff about collections, seems like that I can use them some other ways also.
I will give it a try.
Re: Split Function Struggle!
Too many solutions!
One more way that uses InStrRev() with different approach:
Code:
Sub SplitX()
Dim sText As String
Dim i As Long
Dim ar() As String
sText = "1. Bc4 Na2 2. Ka8 Bc3 3. Bxe4 f2 4. Kc2 Qa4 10. HGj kk 60. Tfg Ygg "
Do
i = InStrRev(sText, ".", i - 1)
If i > 1 Then i = InStrRev(sText, " ", i - 1)
If i > 1 Then Mid$(sText, i, 1) = vbLf Else Exit Do
Loop
ar = Split(sText, vbLf)
'-- Output
For i = 0 To UBound(ar)
Debug.Print ar(i)
Next
End Sub
Re: Split Function Struggle!
Thanks every one. Problem is solved. I am going to mark answers :D