|
|
| Author |
Message |
victorf
Joined: 01 Jan 2006
Posts: 342
Location: Schenectady, New York
|
|
Posted: 11 January 2007, 20:50 PM Post subject: Search a string |
|
|
Suppose I have a string, say S1 and a second string S2 and I wish to search S2 character by character to see if any character in S1 is in S2 and return the position of that character in S2, i.e. S1 = ",*" and S2 contains "ABC,DEF*". I want to search S2 character by character and when the comma is detected the function returns 4 and when the search reaches the star the function returns 8. I believe this is equivalent to the VB InStr function. I want to be able to write something like:
| Code: |
For pos = 1 to Len(S2)
If InStr(S1, S2, pos, 1) then
<do a bunch of stuff>
next pos
|
What would be a somewhat efficient way to do this?
Any enlightenment will be appreciated.
Vic |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR
|
|
Posted: 11 January 2007, 22:40 PM Post subject: |
|
|
| One way to implement this functionality is to use the StrFind() function. I can't say offhand whether it would likely be more efficient to search the subject string up to N times using a single character string created from successive characters of the separator character string or vice versa. My conjecture, assuming that the subject string will generally be longer than the string of separator characters, is that the former would be more efficient. |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR
|
|
Posted: 11 January 2007, 22:46 PM Post subject: Re: Search a string |
|
|
| victorf wrote: | | I believe this is equivalent to the VB InStr function. |
As I read the description of InStr, it is more like the ZBasic function StrFind() than the functionality that you want. The functionality that you described is similar to the C function strpbrk(). I don't know if VB has similar functionality. |
|
| Back to top |
|
 |
victorf
Joined: 01 Jan 2006
Posts: 342
Location: Schenectady, New York
|
|
Posted: 12 January 2007, 12:04 PM Post subject: |
|
|
All I want to do is to extract the values delimited by either character in S1
Can I do the following:
| Code: |
For pos = 1 to Len(S2)
If StrFind(Mid(S2,pos,1), S1) > 0 Then
<do extraction stuff>
End If
Next pos
|
By the way, I had a mistake in my original post:
| Code: |
If InStr(S1, S2, pos, 1) then
|
It should have read:
| Code: |
If InStr(S1, Mid(S2,pos,1)) then
|
Any further enlighten,ent will be appreciated.
Vic |
|
| Back to top |
|
 |
twesthoff
Joined: 17 Mar 2006
Posts: 199
Location: Fredericksburg, VA
|
|
Posted: 12 January 2007, 12:27 PM Post subject: RE: Search a string |
|
|
Vic,
Would you post a sample string please? It will make it easier to find a solution.
Are the two delimiters "*" and "," always in the same order or relative position in each string? If so then there may be more efficient ways to solve the problem.
Are we to assume that each large string is a different length?
Tom |
|
| Back to top |
|
 |
dlh
Joined: 15 Dec 2006
Posts: 287
Location: ~Cincinnati
|
|
Posted: 12 January 2007, 13:17 PM Post subject: |
|
|
Vic,
I think you need to supply more info. It looks like you want something similar to the VB Parse function (introduced with VB5?) but with two different delimiters.
Are you trying to extract the characters between the comma and asterisk?
If so, it probably will be easier to do it in multiple steps.
1. Find the comma
2. Find the asterisk
3. Extract the characters between them
| Code: |
i = StrFind("ABC,DEF*", ",")
ii =StrFind("ABC,DEF*", "*")
str = "ABC,DEF*"
s = Mid(str, i+1, ii-i-1)
|
|
|
| Back to top |
|
 |
victorf
Joined: 01 Jan 2006
Posts: 342
Location: Schenectady, New York
|
|
Posted: 12 January 2007, 13:24 PM Post subject: |
|
|
Tom
OK,
Suppose you have a string S1:
S1 = "ABC,DEF,GHI,JKL;RST;UVW;XYZ"
and the string S2
S2 = ",;"
with the user specified string separators, i.e. comma and semi-comma in this case, in S2
I want to write a function to search for any such separator in S1 and extract the characters between the separators, i.e.
ABC
DEF
GHI
JKL
RST
UVW
XYZ
and place them in a user specified BYREF array. The function will return the number of sub-strings found or -1 if none are found.
I have this function in VB but it uses the VB function InStr like this:
| Code: |
For pos = 1 to Len(S2)
If InStr(S2, (S1, pos, 1)) > 0 then
<do a bunch of stuff>
next pos
|
where the InStr function compares the single character (sub-string) in S1 at position pos with the characters in S2 and if a match is found returns the position in S2 where the character (seperator) is found. If not found the InStr function returns 0.
This is simply a string parser and my VB one works well.
| Quote: |
Are we to assume that each large string is a different length?
|
Yes! And the separators can be different with each call. It is up to the user to assure that the array passed to the function is large enough or some of the string tokens will NOT be returned. The VB parser dynamically redimensions the array (REDIM) in order not to run out of space for tokens. I don't know how to do this in ZBasic
Vic |
|
| Back to top |
|
 |
dlh
Joined: 15 Dec 2006
Posts: 287
Location: ~Cincinnati
|
|
Posted: 12 January 2007, 13:43 PM Post subject: |
|
|
| One thing missing (I think) in the ZBasic implementation of Mid is...which returns "DEF*". It simplifies this type of operation. Of course, there's a work-around using Right but that's not quite as readable. |
|
| Back to top |
|
 |
victorf
Joined: 01 Jan 2006
Posts: 342
Location: Schenectady, New York
|
|
Posted: 12 January 2007, 14:07 PM Post subject: |
|
|
This is the day for mistakes. When I wrote my last post I goofed:
| Code: |
For pos = 1 to Len(S2)
If InStr(S2, (S1, pos, 1)) > 0 then
<do a bunch of stuff>
next pos
|
where I should have written:
| Code: |
For pos = 1 to Len(S2)
If InStr(S2, Mid(S1, pos, 1)) > 0 then
<do a bunch of stuff>
next pos
|
Sorry 'bout that
dlh wrote
| Quote: |
One thing missing (I think) in the ZBasic implementation of Mid is...
s = Mid("ABC,DEF*", 5)
which returns "DEF*". It simplifies this type of operation. Of course, there's a work-around using Right but that's not quite as readable.
|
How about using:
| Quote: |
Mid(str, pos, length)
|
Remember, the function I wish to implement is searching for separators and knows that * is one. and knows how many characters are between the previous , and the * so Mid(str, pos, length) can get the DEF only.
Vic |
|
| Back to top |
|
 |
dlh
Joined: 15 Dec 2006
Posts: 287
Location: ~Cincinnati
|
|
Posted: 12 January 2007, 14:37 PM Post subject: |
|
|
| victorf wrote: |
dlh wrote
| Quote: |
One thing missing (I think) in the ZBasic implementation of Mid is...
s = Mid("ABC,DEF*", 5)
which returns "DEF*". It simplifies this type of operation. Of course, there's a work-around using Right but that's not quite as readable.
|
|
How about using:
| Quote: |
Mid(str, pos, length)
|
I already extracted the substring in my first example. In VB I then use Mid to shorten the main string, dropping the leftmost section already searched. I just repeat this in a Do:Loop until my Parse function returns an empty string.
| Quote: |
Remember, the function I wish to implement is searching for separators and knows that * is one. and knows how many characters are between the previous , and the * so Mid(str, pos, length) can get the DEF only.
|
That's not at all clear from anything you wrote previously. You indicated the delimiters were user defined.
If the substrings are always 3 characters long, why do you need any delimiters? Delimiters are only needed if the substrings vary in length and, even then, a single delimiter is usually sufficient. |
|
| Back to top |
|
 |
twesthoff
Joined: 17 Mar 2006
Posts: 199
Location: Fredericksburg, VA
|
|
Posted: 12 January 2007, 14:47 PM Post subject: RE: Search a string |
|
|
Vic,
The Zbasic FindStr() does the same thing as Instr() so your VB code should work with little modification using FindStr().
I don't think there is any way in Zbasic to REDIM an array, so you will have to make it big enough to handle the largest items you expect.
There is more than one way to do what you want, so I am sure you can get it to work. Dlh had a good idea in a previous post...
Tom |
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Posts: 2593
Location: Portland, OR
|
|
Posted: 12 January 2007, 16:40 PM Post subject: |
|
|
| Several months ago, I posted some code for splitting a string using a single delimiter string. It could be modified to treat the delimiter string as multiple possible delimiters as you required. Note, also, that my function is designed to be called repeatedly, if necessary, to completely process the string. This capability works around the potential problem caused by the lack of re-dim capability and still handles strings with a large number of sub-elements. |
|
| Back to top |
|
 |
|