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/