A simpler regular expression to parse quoted strings
Define the pattern once and use the global g
flag.
var matches = str.match(/'[^']*'/g);
If you want the tokens without the single quotes around them, the normal approach would be to use sub-matches in REGEX - however JavaScript doesn't support the capturing of sub-groups when the g
flag is used. The simplest (though not necessarily most efficient) way around this would be to remove them afterwards, iteratively:
if (matches)
for (var i=0, len=matches.length; i<len; i++)
matches[i] = matches[i].replace(/'/g, '');
[EDIT] - as the other answers say, you could use split()
instead, but only if you can rely on there always being a space (or some common delimiter) between each token in your string.
When a regex object has the the global
flag set, you can execute it multiple times against a string to find all matches. It works by starting the next search after the last character matched in the last run:
var buf = "'abc' 'def' 'ghi'";
var exp = /'(.*?)'/g;
for(var match=exp.exec(buf); match!=null; match=exp.exec(buf)) {
alert(match[0]);
}
Personally, I find it a really good way to parse strings.
EDIT: the expression /'(.*?)'/g
matches any content between single-quote ('), the modifier *?
is non-greedy and it greatly simplifies the pattern.
A different approach
I came here needing an approach that could parse a string for quotes and non quotes, preserve the order of quotes and non quotes, then output it with specific tags wrapped around them for React or React Native so I ended up not using the answers here because I wasn't sure how to get them to fit my need then did this instead.
function parseQuotes(str) {
var openQuote = false;
var parsed = [];
var quote = '';
var text = '';
var openQuote = false;
for (var i = 0; i < str.length; i++) {
var item = str[i];
if (item === '"' && !openQuote) {
openQuote = true;
parsed.push({ type: 'text', value: text });
text = '';
}
else if (item === '"' && openQuote) {
openQuote = false;
parsed.push({ type: 'quote', value: quote });
quote = '';
}
else if (openQuote) quote += item;
else text += item;
}
if (openQuote) parsed.push({ type: 'text', value: '"' + quote });
else parsed.push({ type: 'text', value: text });
return parsed;
}
That when given this:
'Testing this "shhhh" if it "works!" " hahahah!'
produces that:
[
{
"type": "text",
"value": "Testing this "
},
{
"type": "quote",
"value": "shhhh"
},
{
"type": "text",
"value": " if it "
},
{
"type": "quote",
"value": "works!"
},
{
"type": "text",
"value": " "
},
{
"type": "text",
"value": "\" hahahah!"
}
]
which allows you to easily wrap tags around it depending on what it is.
https://jsfiddle.net/o6seau4e/4/