Basically, I’m being passed a string and I need to tokenise it in much the same manner as command line options are tokenised by a *nix shell
Say I have the following string
"Hello\" World" "Hello Universe" Hi
How could I turn it into a 3 element list
- Hello” World
- Hello Universe
- Hi
The following is my first attempt, but it’s got a number of problems
- It leaves the quote characters
- It doesn’t catch the escaped quote
Code:
public void test() {
String str = "\"Hello\\\" World\" \"Hello Universe\" Hi";
List<String> list = split(str);
}
public static List<String> split(String str) {
Pattern pattern = Pattern.compile(
"\"[^\"]*\"" + /* double quoted token*/
"|'[^']*'" + /*single quoted token*/
"|[A-Za-z']+" /*everything else*/
);
List<String> opts = new ArrayList<String>();
Scanner scanner = new Scanner(str).useDelimiter(pattern);
String token;
while ((token = scanner.findInLine(pattern)) != null) {
opts.add(token);
}
return opts;
}
So the incorrect output of the following code is
- “Hello\”
- World
- ” “
- Hello
- Universe
- Hi
EDIT I’m totally open to a non regex solution. It’s just the first solution that came to mind
If you decide you want to forego regex, and do parsing instead, there are a couple of options. If you are willing to have just a double quote or a single quote (but not both) as your quote, then you can use StreamTokenizer to solve this easily:
If you must support both quotes, here is a naive implementation that should work (caveat that a string like ‘”blah \” blah”blah’ will yield something like ‘blah ” blahblah’. If that isn’t OK, you will need to make some changes):