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
"{[^{}]*}"|\{([^}]+)\}
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.
"{[^{}]+}"?|{[^{}]+}"|{([^{}]+)}
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.
jex.im visualizes regular expressions:
We can possibly look at some other boundaries too:
(?:\s|^){([^}]*)}(?:\s|$)
I would just match the part with the quotes first, and keep the part in the braces in a capture group.
"[^"]*"|\{([^}]*)\}
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.