Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting a string by space, ignoring spaces in nested strings

Tags:

javascript

Currently, I can split a string like this:

"1 2 3".split(' ') // [ "1", "2", "3" ]
"1 2 3 'word'".split(' ') // [ "1", "2", "3", "'word'" ]

Is there a way to avoid splitting on a space within a nested string?

For example:

"1 2 3 'word one'".split(' ') // want output of [ "1", "2", "3", "'word one'" ]
"1 2 3 \"word one\"".split(' ') // want output of [ "1", "2", "3", "\"word one\"" ]

I want output of [ "1", "2", "3", "'word one'" ] instead of [ "1", "2", "3", "'word", "one'" ] (i.e. I want to ignore spaces if they are in strings).

like image 580
Kwoppy Avatar asked Nov 19 '25 11:11

Kwoppy


2 Answers

One approach can be to use match with a regex that accounts for the spaces inside quotes:

var s = "1 2 3 \"word one\" one \"two\" 'hello world'";

console.log(s.match(/'[^']+'|"[^"]+"|\w+/g));

Edit: See Certain Performance's answer for a better regex.

like image 167
slider Avatar answered Nov 21 '25 02:11

slider


To correctly match strings containing additional quote characters, when matching substrings in quotes, lazy-repeat the . with .+?, otherwise strings such as

1 "2" "3"

won't match properly. Also, unless you can count on all matches containing just word characters, probably better to use \S (which will match anything but whitespace characters):

var s = `1 "2" "3" foo'bar`
console.log(s.match(/'.+?'|".+?"|\S+/g));

Or, to be slightly more efficient, rather than lazy repetition, use negative character classes instead:

var s = `1 "2" "3" foo'bar`
console.log(s.match(/'[^']+'|"[^"]+"|\S+/g));
like image 24
CertainPerformance Avatar answered Nov 21 '25 00:11

CertainPerformance