You can do it all in one line using split()
with the right regex:
String[] array = source.replaceAll("^[^']+", "").split("(?<!\\G.)(?<=').*?(?='|$)");
There's a reasonable amount of regex kung fu going on here, so I'll break it down:
- The delimiter is wrapped by even/odd quotes, but can not contain the quotes because
split()
consumes the delimiter, so a look behind (?<=')
and look ahead (?=')
(which are non-consuming) is used to match the quotes instead of a literal quote in the regex
- a reluctant match
.*?
for characters between the quotes ensures that it stops at the next quote (instead of matching through to the last quote)
- I added an alternate match for end of input tot he look ahead
(?='|$)
in case there's no trailing close quote
- And saving the best for last, the regex that is key to making this all work is the negative look behind
(?<!\\G.)
which means "don't match on the end of the previous match" and ensures the next match advances past the end of the previous delimiter, without which you would end up with just the quote characters in your array. \G
matches the end of the previous match, but also matches start of input for the first match, so it rather neatly automatically handles not matching on the first quote - thus making the delimiter wrapped in even/odd quote instead of odd/even as it would be otherwise.
- To cater for the input's first character not being a quote, you need to strip off the leading characters before splitting - that's why the
replaceAll()
is needed
Here's some test code using your sample input:
String source = "'qty'=>'<input type=\"text\" maxlength=\"3\" class=\"qty_text\" id='.$key.' value ='";
String[] array = source.replaceAll("^[^']+", "").split("(?<!\\G.)(?<=').*?(?='|$)");
System.out.println(Arrays.toString(array));
Output:
['qty', '<input type="text" maxlength="3" class="qty_text" id=', ' value =']