Subject: Re: string processor From: Erik Naggum <erik@naggum.net> Date: 2000/08/10 Newsgroups: comp.lang.lisp Message-ID: <3174939482743037@naggum.net> * fsumera@cs.rmit.edu.au (Irma) | is there any way to seperate parts of a sentence There's the function position to find the position of a single element in a sequence, and the function search to locate a subsequence. Then there's the function subseq to extract a subsequence. | (something like stringtokenizer in java) Well, instead of implementing a class like StringTokenizer with Enumerator stuff like hasMoreElements and nextElement, the customary Common Lisp approach is to return a list of tokens. Whether you wish to iterate over the returned sequence of tokens or do something else is up to you, but if so, you do it with ordinary list traversal. | for example i've got the string : "things1 : things2" | and i want to seperate them by the ':' There are basically two kinds of separators: Individual characters (such as are implemented by java.util.StringTokenizer) and strings. I tend to favor the strings model, as that allows more interesting cases. Individual characters is also a subcase of strings. There are also basically two ways to deal with separators: Either you select any from a set repeatedly (StringTokenizer default), or you match the separators in a list in order (nextElement with an argument). Then there are basically two ways to return tokens: Either your separators are noise and you discard them, or you return them as tokens in their own right (both are available, determinable by the returnTokens argument to the constructor). Finally, there are basically two ways to treat two separators back to back in the target string: Either it means there is an empty token between them, or there isn't (the StringTokenizer way). Suppose we make a random sampling of decisions and choose strings in order that are not significant but with empty elements in between. (Symbols with <> around them would be lambda-bound.) (loop for delimiter in <delimiters> for match-start = <start> then next for match-end = (search delimiter <target> :start2 match-start :end2 <end>) with next while match-end collect (subseq <target> match-start match-end) do (setq next (+ match-end (length delimiter)))) <start> would default to 0, <end> to nil (which means the length of the target sequence). Incidentally, note that none of the code above knows it's dealing with strings, but it would be very inefficient for lists of stuff. Considering the number of options, and the ease with which you can write a loop that collects your particular substrings, this is an argument for the software-pattern mode of solution, specifically that using the general form is more complex than using the pattern. This was highlighted by a long-winded discussion on how to implement a tokenizer some time ago -- it grew ever more powerful and harder to use. Incidentally, I think java.util.StringTokenizer is silly both in its limitedness and its complexity of use, but studying Java is not a very entertaining task, except maybe if you're coming at Java from below, like from C++. | I've been using the 'read-from-string' function to get one string at | a time but i guess that must be a better way to that. You _really_ don't want to use the Lisp reader unless you have Lisp objects of some sort. Just trust me on this for now -- there's no need to figure it out the hard way. #:Erik -- If this is not what you expected, please alter your expectations.