8

Greetings, I am the program writer for the rebellion against the evil galactic empire. Right now, we are preparing for a daring assault on the Death Star.

I have created a vast database of information about our pilots, droids, and systems aboard our X-Wing and Y-Wing fighters that will soon assault the Death Star. Because of our critical needs to access the information quickly, I have designed a system where a user can enter a string of text to specify what data they want to retrieve.

There are numerous fields the user may search by. For example, if a user wants to find data about R2D2, he could type in the query "DROID:R2D2" and quickly find this data. If he needs the data about all the pilots, droids, and systems for Red Team, he could enter "TEAM:RED TEAM".

However, the system is designed to handle more complex queries. As you can see from the previous query, the data field name and data value are seperated by a colon : character. The users must be able to search multiple values per field and search multiple fields all at once.

Here is a query typical of my more advanced users: "SHIPTYPE:X-WING,Y-WING; LOCATION:docking bay 94; DROIDTYPE:R2"

I am quite happy with the way I have handled this. I use the String.Split(';') function to read to get the values of the three data fields the user has selected. I use String.Split(':') to seperate the data field name from the value, and then I userString.Split(',')` to get the different field values where the user has entered more than one. You can see how this works.

However, there is one problem. Princess Leiah (You know how fussy she is) insists on using ':', ';', and ',' in her blaster calibration records. When she tries to query this data, her queries are unintelligible to my program. She says that the Death Star will destroy the rebel base soon if this problem is not corrected.

Therefore, I ask for you help in suggesting good practices for parsing user inputs. How can I get my program working for Princess Leiah?

Update I will speculate about the answer to my own question. When I learned to program in C-flavored languages, I learned about "escape-sequences" where I can specify an ordinarily reserved character in my string literals. (eg, A " character ordinarily terminates a string literal, but I can "escape" it using \") I'm guessing that it would be a good idea to do something similiar with my program, but I don't know what would be the best way of accomplishing it. Prior to preparing for this Death Star assault, most of my programming experience has been with the binary language of moisture vaporators, so this is new to me.

Vivian River
  • 31,198
  • 62
  • 198
  • 313
  • 4
    Translation: "I'm using semi-colon, colon, and comma as delimiters - but some values naturally contain those characters. How can I work around this situation?" Is that about right? – Jon Skeet Feb 28 '11 at 16:18
  • That is the my question. However, I don't have much experience with this sort of programming issue, so I wanted to be up front with what I'm doing. I've been surprised at how often I ask a question on SO and it turns out to be the wrong question. – Vivian River Feb 28 '11 at 16:20
  • Thanks for the translation Jon. That's 5 mins of my life I won't get back! – Jon Egerton Feb 28 '11 at 16:21
  • at first I thought I accidentally reached [SciFi-Stackexchange-Beta](http://scifi.stackexchange.com/) until I read Jons translation comment. – froeschli Mar 01 '11 at 08:09
  • you might be interested in [this SO question](http://stackoverflow.com/questions/667803/what-is-the-best-algorithm-for-arbitrary-delimiter-escape-character-processing) and the [accepted answer](http://stackoverflow.com/questions/667803/what-is-the-best-algorithm-for-arbitrary-delimiter-escape-character-processing/674482#674482). Hope it helps. – froeschli Mar 01 '11 at 08:24

3 Answers3

3

In similar fashion to Google, you could allow for search terms to be enclosed in " marks. So you'd allow:

SHIPTYPE:"BATTLESTAR:GALACTICA"; LOCATION:docking bay 94; DROIDTYPE:R2

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
  • +1 @JonEgerton simple, elegant, people already know how to do it! – msarchet Feb 28 '11 at 16:27
  • In order to implement this solution, what String parsing methods would be most appropriate? – Vivian River Feb 28 '11 at 16:29
  • I would investigate using Regex.Split as a possiblity, although I'm not going to pretend to know what the regex pattern would be. Probably good for another SO question! Alternatively I think its down to donkey work going through the string and breaking it down manually. Personally I'd consider a design change and do a simple query builder with dropdowns/checkbox lists. That way you're not subject to typos from users, and users don't have to know exactly how some of the more complex names are syntaxed. – Jon Egerton Feb 28 '11 at 16:48
  • Actually Jon, there is a page with dropdowns/checkbox lists as you suggest. I thought it would be convenient to give power-users a faster way to make on-the-fly queries. – Vivian River Feb 28 '11 at 17:49
  • What if the query contains an `"`? – BlueRaja - Danny Pflughoeft Feb 28 '11 at 21:19
  • Double quote it ala VB:- SHIPTYPE:"ONE""TWO""THREE". No-one said this would be easy! ;-) – Jon Egerton Feb 28 '11 at 23:28
2

I'm sorry but the Star Wars description didn't help to clarify your question.

At any rate, I've written a lot of parsing code. I don't care much for String.Split() unless the data will always be formatted just so. There is a general-purpose parser class at http://www.blackbeltcoder.com/Articles/strings/a-text-parsing-helper-class. I would probably use something like that to implement a more flexible parser.

Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
2

It seems that you are using Keywords on the left side of the delimiter and the actual query value on the right side of the delimiter. You could try something where you check to see if the word contained between the ; and the : is a actual keyword and if it isn't ignore the delimiter at that point.

However that won't be simple, nor will it work solely with String.Split()

msarchet
  • 15,104
  • 2
  • 43
  • 66