Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBP] General String-parsing function

Author
Message
calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 14th Aug 2008 15:18 Edited at: 14th Aug 2008 17:53
The following function can obtain any parameter from a long string. The code is rather lenient, allowing the user to add spurious spaces (which are ignored). Here's the function, subroutine, and an example:



The optomist's right, The pessimist's right.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 14th Aug 2008 15:28
That's pretty neat. I remember when I started getting into string parsing - it was a big bad new world for me, lol.

I've updated your code a bit. I've fixed the indentation and I removed the need for a global variable (this can get pretty annoying having to use it). If the query doesn't match anything then it just returns a blank.



Don't you just hate that Zotoaster guy?
calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 14th Aug 2008 17:22 Edited at: 14th Aug 2008 17:53
Oops, I made a mistake! Here's a repaired version (of Zotoaster's):



The optomist's right, The pessimist's right.
Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 15th Aug 2008 03:51
Calcyman,

A little tip, If you're planning upon parsing a lot of strings, then there's a few bottle necks in it given how DBpro works. One easy opt, is to precalc the length of A$ outside of the parsing loop. From memory Dbpro evaluates the destination expression in FOR/NEXT loops each iteration. So the expression For i = 1 to len(a) means that for each time we step through the loop Db is resolving the string length of A. Now from what i can tell, A never changes, therefore it's length never changes so we can precalculate it's that and just substitute it back in.

A bit like this (snippet untested!)





Another little tip is that string comparisons are pretty heavy. So when comparing for individual characters, it's generally best to grab a chr as ASC II value then compare it with the CHR values. Ie

ThisChr=mid(SomeString$,lp)

if ThisCHR=32 then Print "Space"
if ThisCHR=61 then Print "Equals"

etc

calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 15th Aug 2008 12:40
Thanks for the advice. I thought that using ASC() would actually slow it down, rather than speed it up. Actually your code should be:

ThisChr=ASC(mid(SomeString$,lp))

It would be better if there was a seperate char datatype, like in C++, and that MID$() could return char as well as string values. That would be even faster for single-character comparisons.

The optomist's right, The pessimist's right.
Kevin Picone
21
Years of Service
User Offline
Joined: 27th Aug 2002
Location: Australia
Posted: 16th Aug 2008 02:02
Nah, the above is correct. It's PlayBasic code however. Forget, where i was for a second .

If such a routine is going to put under stress (parsing lots of properties) then moving down the pointer road would indeed be beneficial, if not, a mem block solution may well be the next best thing. I can't recall if Dbpro support getting points to string or not however. If it doesn't, i'm sure IanM has a plug it for it.

IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 16th Aug 2008 15:53 Edited at: 16th Aug 2008 18:16
Getting ascii values from a string is a good idea and I'll add functions specifically for this and searching for them in the next release of my plug-ins.

There are many ways to do this using my plug-ins.
1. Using the SPLIT STRING command, splitting on commas and equals. Look for the word, when found, check that the previous delimiter was a comma and the next was an equal, then return the following word.
2. Using INSTR to find matches, then searching back for commas and forward for equals to confirm the match, then forward again to look for the following comma or EOS.
3. Going low-level, looking at bytes - it'd pretty much be coding C using DBPro. You can get the string address using the GET STRING PTR function, and character values using PEEK BYTE and the rest is up to you.

I'd suspect that with the new functions that the second option would be slightly faster (purely due to a reduced number of function calls), and maybe a hybrid of 2 and 3 might be slightly faster than that (reduced string bounds checking).

[EDIT]Turns out that option 1 is the fastest on average and the cleanest code:

Look how simple the code is.

I can get a hybrid of 2 & 3 to go faster, but a false detection by the INSTR function makes the function many times slower.

Cash Curtis II
19
Years of Service
User Offline
Joined: 8th Apr 2005
Location: Corpus Christi Texas
Posted: 17th Aug 2008 11:21
Split String is one of the greatest commands ever invented, not only because of it's usefulnes but it's speed as well.


Come see the WIP!
calcyman
16
Years of Service
User Offline
Joined: 31st Aug 2007
Location: The Uncertainty Principle
Posted: 19th Aug 2008 22:59
Agreed. If, however, you don't have IanM's plugin (or simply don' want to use any external plugins), you will have to use a string-searching routine (like mine).

The optomist's right, The pessimist's right.

Login to post a reply

Server time is: 2024-05-18 13:48:38
Your offset time is: 2024-05-18 13:48:38