dina
dina

Reputation: 4289

regex match uneascaped quoted string

I am trying to match quoted strings in a sentence with regex, matching strings closed with quotes and also string at end of sentence which have only opening quotes.

For example in the sentence concat("hello ", name, "how are, I will match "hello" and "how are.

This is my regex which works well

reg = /"[^"]*"?/g
input = 'concat("hello ",  name, "how are';
[...input.matchAll(reg)].map(m => m[0])
/** output:
[ 
  '"hello "', 
  '"how are' 
]


 */

but it fails when there is a backslashed quote.
For example for the sentence:
concat("say \"hello\" to ", name, "and to I would like to match "say \"hello\" to", and "and to, but thhis is what the regex matches:

reg = /"[^"]*"?/g
input = 'concat("say \\"hello\\" to ",  name, "and to'
[...input.matchAll(reg)].map(m => m[0])
/** output (not the one I am trying to get):
[ 
  '"say \\"', 
  '" to "', 
  '"and to' 
]
 */

I tried adding to regex (?<!\\) before every ", so it matches only quotes that are no backslashed, but still get wrong result:

reg = /(?<!\\)"[^(?<!\\)"]*(?<!\\)"?/g
input = 'concat("say \\"hello\\" to ",  name, "and to'
[...input.matchAll(reg)].map(m => m[0])
/** result:
[ 
  '"say ', 
  '",  name, "' 
]

*/

what would be the correct regex?

Upvotes: 0

Views: 69

Answers (1)

awarrier99
awarrier99

Reputation: 3855

This should do what you're looking for:

const reg = /"(?:\\\\|\\"|[^"])*"?/g;
const input1 = 'concat("say \\"hello\\" to ",  name, "and to';
const input2 = 'CONCAT("\\\\", name';
console.log([...input1.matchAll(reg)].map(m => m[0]));
console.log([...input2.matchAll(reg)].map(m => m[0]));

Edit: I updated the regex to account for the case where the backslash may itself be escaped

Upvotes: 2

Related Questions