简体   繁体   中英

Regex to match anything between braces except when quoted

Does anyone know the best approach with regex to find anything in a string between braces, except when quoted. Example:

This is my {string between braces} which the pattern should match, but this "{string between braces}" should be ignored.

This regex will get me anything between braces...

/\{([^}]+)\}/g

Edit:

For those who have provided potential solutions so far, i thank you. To those who have questioned the ambiguity of this, apologies, it was quickly fired off with the intention of coming back to edit.

Given the following scenarios:

var str1 = 'Lorem ipsum dolor {sit} amet, consectetur {adipiscing} elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';

Expect Result: {sit} and {adipiscing} be matched

var str2 = 'Lorem "ipsum "dolor {sit} amet", consectetur" {adipiscing} elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';

Expected Result: {sit} and {adipiscing} be matched (since neither are between open quotes)

var str3 = 'Lorem ipsum "dolor {sit} amet", consectetur {adipiscing} elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua';

Expected Result: {adipiscing}

For the purpose of clarity, in terms quotes, we are talking quotes only, not apostrophes.

One option is to match all the strings that start with "{...}" and capture the alternative using an alternation in a group

"{[^{}]*}"|\{([^}]+)\}

Regex demo

 const regex = /"{[^{}]*}"|\\{([^}]+)\\}/g; const str = `{string between braces} "{string between braces 2}" `; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } if (m[1]) { console.log(m[1]); } }

Another option is to also match either a " at the start or either a " at the end to not capture the group when having a single double quote.

"{[^{}]+}"?|{[^{}]+}"|{([^{}]+)}

Regex demo

In parts

  • "{[^{}]+}"? Match from opening "{ till closing } and optional "
  • | Or
  • {[^{}]+}" Match from opening { till closing } and "
  • | Or
  • { Match opening {
  • ([^{}]+) Capture group 1, match 1+ times any char except { or }
  • } Match closing }

 const regex = /"{[^{}]+}"?|{[^{}]+}"|{([^{}]+)}/g; const strings = [ '{string between braces}', '"{string between braces 2}"', '"{string between braces 3}', '{string between braces 4}"', 'start"{str5}"{str6}"end' ].forEach(s => { let m; while ((m = regex.exec(s)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } if (m[1]) { console.log(m[1]); } } });

Maybe,

{([^}]*)}(?!")

might be close.

 const regex = /{([^}]*)}(?!")/gm; const str = `This is my {string between braces} which the pattern should match, but this "{string between braces}" should be ignored`; let m; while ((m = regex.exec(str)) !== null) { // This is necessary to avoid infinite loops with zero-width matches if (m.index === regex.lastIndex) { regex.lastIndex++; } m.forEach((match, groupIndex) => { console.log(`Found match, group ${groupIndex}: ${match}`); }); }


If you wish to simplify/update/explore the expression, it's been explained on the top right panel of regex101.com . You can watch the matching steps or modify them in this debugger link , if you'd be interested. The debugger demonstrates that how a RegEx engine might step by step consume some sample input strings and would perform the matching process.


RegEx Circuit

jex.im visualizes regular expressions: 在此处输入图片说明


We can possibly look at some other boundaries too:

(?:\s|^){([^}]*)}(?:\s|$)

RegEx Demo

I would just match the part with the quotes first, and keep the part in the braces in a capture group.

"[^"]*"|\{([^}]*)\}

regex101 demo

 const re = /"[^"]*"|\\{([^}]*)\\}/g; const str = `there is a {braced part} that's a "quoted {braced part}"`; let match; while ((match = re.exec(str)) !== null) { if (match.index === re.lastIndex) { re.lastIndex++; } if (match[1]) { console.log(match[1]); } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM