Split a string by whitespace, keeping quoted segments, allowing escaped quotes
You can change your regex to:
keywords = keywords.match(/\w+|"(?:\\"|[^"])+"/g);
Instead of [^"]+
you've got (?:\\"|[^"])+
which allows \"
or other character, but not an unescaped quote.
One important note is that if you want the string to include a literal slash, it should be:
keywords = 'pop rock "hard rock" "\\"dream\\" pop"'; //note the escaped slashes.
Also, there's a slight inconsistency between \w+
and [^"]+
- for example, it will match the word "ab*d"
, but not ab*d
(without quotes). Consider using [^"\s]+
instead, that will match non-spaces.
ES6 solution supporting:
- Split by space except for inside quotes
- Removing quotes but not for backslash escaped quotes
- Escaped quote become quote
- Can put quotes anywhere
Code:
keywords.match(/\\?.|^$/g).reduce((p, c) => {
if(c === '"'){
p.quote ^= 1;
}else if(!p.quote && c === ' '){
p.a.push('');
}else{
p.a[p.a.length-1] += c.replace(/\\(.)/,"$1");
}
return p;
}, {a: ['']}).a
Output:
[ 'pop', 'rock', 'hard rock', '"dream" pop' ]