Regex to get string between curly braces
Asked Answered
W

17

157

Unfortunately, despite having tried to learn regex at least one time a year for as many years as I can remember, I always forget as I use them so infrequently. This year my new year's resolution is to not try and learn regex again - So this year to save me from tears I'll give it to Stack Overflow. (Last Christmas remix).

I want to pass in a string in this format {getThis}, and be returned the string getThis. Could anyone be of assistance in helping to stick to my new year's resolution?


Related questions on Stack Overflow:

Whipping answered 5/1, 2009 at 13:21 Comment(3)
This question has been added to the Stack Overflow Regular Expression FAQ, under "Advanced Regex-Fu".Survival
@Kobi: The FAQ is a wiki. Anyone can edit it. So edit it.Survival
In JS, once I have the string with the braces from the first answer here, I'd do str.replace('{','').replace('}','').trim()Shady
O
66

If your string will always be of that format, a regex is overkill:

>>> var g='{getThis}';
>>> g.substring(1,g.length-1)
"getThis"

substring(1 means to start one character in (just past the first {) and ,g.length-1) means to take characters until (but not including) the character at the string length minus one. This works because the position is zero-based, i.e. g.length-1 is the last position.

For readers other than the original poster: If it has to be a regex, use /{([^}]*)}/ if you want to allow empty strings, or /{([^}]+)}/ if you want to only match when there is at least one character between the curly braces. Breakdown:

  • /: start the regex pattern
    • {: a literal curly brace
      • (: start capturing
        • [: start defining a class of characters to capture
          • ^}: "anything other than }"
        • ]: OK, that's our whole class definition
        • *: any number of characters matching that class we just defined
      • ): done capturing
    • }: a literal curly brace must immediately follow what we captured
  • /: end the regex pattern
Orchidaceous answered 5/1, 2009 at 13:25 Comment(17)
not to be nitpicky but shouldnt the code be g.substring(1,g.length-2)Mina
Actually, it shouldn't. substring() is 0-based, whereas the length is 1-based, and substring()'s second argument is which position in the original string to stop at, rather than how long the string returned should be. Try it for yourself, and then try with 5 as the first argument. (The above I actually just copied and pasted from Firebug, to make sure it was initially correct.)Orchidaceous
Substringing is one of those things that changes based on the language you work in. Javascript takes the index to stop at, PHP takes the length of the desired end result (unless it's negative, in which case it takes the number of characters to remove), C# is different again...nice and confusing.Warranty
...and Python just has slicing, which IMO is better than anything else :p.Pyrography
Sweet, but not sure how that's a regular expression. Perhaps he was asking for regex, and I came here for the same answer.. sadly the answer has nothing to do with the question..Goldbrick
@baash05, if you read the whole question, the OP didn't even want to learn regex, so I don't think it's the academic exercise you seem to be suggesting it was.Orchidaceous
@Darron thanks for your encouragement. Whenever I get a downvote on this I get to read your comment first. :)Orchidaceous
I wanted to do -1 because the question is asking for regex, I was searching for regex, but the accepted answer was completely useless for me (while the question seemed very promising itself). After reading the first comment I must admit that if I were to answer this question first I could have answered the same/similar way... So in the end, +1.Stuff
Downvoted for not answering the question. OP asked for regex. It is inappropriate to assume the use case when it is not stated. For example, perhaps OP would like a universal rule to store in a database that will work in multiple languages to apply the same validation on both the frontend and backend. Do not rescope a question without certainty that your use case fits the need.Groome
@Groome The OP was tagged JavaScript. If the OP wanted a multi-language solution, I would still say that a regex is overkill in this case, and every language has its equivalent of this much more efficient approach. I didn't rescope--I used all the information available. Also, the OP is the one who marked my answer as accepted, no?Orchidaceous
@Orchidaceous It is tagged javascript and regex. Questions remain public so they will help anyone else with the same issue in the future, regardless of whether the asker explicitly chose your answer. Answers inconsistent with the framing of the question lead to other similar questions being closed as dupes without really being answered. Regex is overkill when it does greedy or reverse lookups, otherwise it is quite performant.Groome
@Groome And if someone has the exact same requirements, I still maintain that this is the best approach. Sometimes when clients say "give me this solution" you have to look underneath their question for what the problem actually is, otherwise you spend a lot of extra time implementing something dubious based on their incorrect assumptions. This is no different.Orchidaceous
He asked for a regex, it’s right in the title. The downvote stands, get over it.Groome
OK now I'm really confused, I've updated my answer to provide a regex, and I'm still getting downvotes.Orchidaceous
@Groome ... and yet he accepted this answer with NO regex. I guess he didn't actaully want the regex after all... he just wanted a simple solution to his problem. Sometimes people think they know the best way to solve a problem... sometimes they need to be shown a better way.Delmydeloach
In C++ getting "bad_brace" error when trying your regexAngell
@MichaelIV, thank you for pointing this out. However, the OP tagged this as JS rather than C++, so...YMMV. ;)Orchidaceous
X
288

Try

/{(.*?)}/

That means, match any character between { and }, but don't be greedy - match the shortest string which ends with } (the ? stops * being greedy). The parentheses let you extract the matched portion.

Another way would be

/{([^}]*)}/

This matches any character except a } char (another way of not being greedy)

Xylotomous answered 5/1, 2009 at 13:24 Comment(8)
this is excellent, but is it possible to match anything between a variable number of curly-bracket-combinations? E.g.: "{this should be matched}this shouldnt{this kinda should again}and so {on}"? I'd like to retrieve the value, which is not within curly brackets. Also: curly brackets will not be used in the sentence and there is no stacking (this would never occure: "{some {text}}"). Anyone an idea how to do it :)? Thanks! (p.s.: upvoted this solution)Petes
It does not capture everything between the curly brackets, it captures everything between the curly brackets AND the curly brackets themselves. How would you go about ONLY capturing what is inside the curly brackets?Sagitta
The parentheses capture the chars between the curly brackets.Xylotomous
I like it that you don't need to escape the curly braces here as the regex parser seems to realise that they're not a quantifier ... well, I'm doing this in python, but I presume javascript regexes work like that tooAssagai
So how would that be for any number of repetitions? This only matches the first one.Hathaway
Adding a g at the end makes it a global search. See a working exampleConcretize
+1 for the "the ? stops the * beeing greedy", I'll have a further look at this. I always used the [^] solution but always found it not really nice...Dunne
@Reality-Torrent, I too saw that it captured the curly brackets if I specify the g option to get all matches. Turns out I should use Regex.exec in a loop instead of string.match in Javascript to have both the g flag, and allowing for capture group. See developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Entwine
G
166
/\{([^}]+)\}/

/        - delimiter
\{       - opening literal brace escaped because it is a special character used for quantifiers eg {2,3}
(        - start capturing
[^}]     - character class consisting of
    ^    - not
    }    - a closing brace (no escaping necessary because special characters in a character class are different)
+        - one or more of the character class
)        - end capturing
\}       - the closing literal brace
/        - delimiter
Grodin answered 5/1, 2009 at 13:59 Comment(3)
@Grodin sa = s.split("/\{([^}]+)\}/"); gives a compile error. illegal repetition, invalid escape character.Coheman
@Anil you appear to be using a string as your split argument rather than a regular expression. What are you trying to do?Grodin
Very clear and useful, this must be the answer more voted.Fabulist
O
66

If your string will always be of that format, a regex is overkill:

>>> var g='{getThis}';
>>> g.substring(1,g.length-1)
"getThis"

substring(1 means to start one character in (just past the first {) and ,g.length-1) means to take characters until (but not including) the character at the string length minus one. This works because the position is zero-based, i.e. g.length-1 is the last position.

For readers other than the original poster: If it has to be a regex, use /{([^}]*)}/ if you want to allow empty strings, or /{([^}]+)}/ if you want to only match when there is at least one character between the curly braces. Breakdown:

  • /: start the regex pattern
    • {: a literal curly brace
      • (: start capturing
        • [: start defining a class of characters to capture
          • ^}: "anything other than }"
        • ]: OK, that's our whole class definition
        • *: any number of characters matching that class we just defined
      • ): done capturing
    • }: a literal curly brace must immediately follow what we captured
  • /: end the regex pattern
Orchidaceous answered 5/1, 2009 at 13:25 Comment(17)
not to be nitpicky but shouldnt the code be g.substring(1,g.length-2)Mina
Actually, it shouldn't. substring() is 0-based, whereas the length is 1-based, and substring()'s second argument is which position in the original string to stop at, rather than how long the string returned should be. Try it for yourself, and then try with 5 as the first argument. (The above I actually just copied and pasted from Firebug, to make sure it was initially correct.)Orchidaceous
Substringing is one of those things that changes based on the language you work in. Javascript takes the index to stop at, PHP takes the length of the desired end result (unless it's negative, in which case it takes the number of characters to remove), C# is different again...nice and confusing.Warranty
...and Python just has slicing, which IMO is better than anything else :p.Pyrography
Sweet, but not sure how that's a regular expression. Perhaps he was asking for regex, and I came here for the same answer.. sadly the answer has nothing to do with the question..Goldbrick
@baash05, if you read the whole question, the OP didn't even want to learn regex, so I don't think it's the academic exercise you seem to be suggesting it was.Orchidaceous
@Darron thanks for your encouragement. Whenever I get a downvote on this I get to read your comment first. :)Orchidaceous
I wanted to do -1 because the question is asking for regex, I was searching for regex, but the accepted answer was completely useless for me (while the question seemed very promising itself). After reading the first comment I must admit that if I were to answer this question first I could have answered the same/similar way... So in the end, +1.Stuff
Downvoted for not answering the question. OP asked for regex. It is inappropriate to assume the use case when it is not stated. For example, perhaps OP would like a universal rule to store in a database that will work in multiple languages to apply the same validation on both the frontend and backend. Do not rescope a question without certainty that your use case fits the need.Groome
@Groome The OP was tagged JavaScript. If the OP wanted a multi-language solution, I would still say that a regex is overkill in this case, and every language has its equivalent of this much more efficient approach. I didn't rescope--I used all the information available. Also, the OP is the one who marked my answer as accepted, no?Orchidaceous
@Orchidaceous It is tagged javascript and regex. Questions remain public so they will help anyone else with the same issue in the future, regardless of whether the asker explicitly chose your answer. Answers inconsistent with the framing of the question lead to other similar questions being closed as dupes without really being answered. Regex is overkill when it does greedy or reverse lookups, otherwise it is quite performant.Groome
@Groome And if someone has the exact same requirements, I still maintain that this is the best approach. Sometimes when clients say "give me this solution" you have to look underneath their question for what the problem actually is, otherwise you spend a lot of extra time implementing something dubious based on their incorrect assumptions. This is no different.Orchidaceous
He asked for a regex, it’s right in the title. The downvote stands, get over it.Groome
OK now I'm really confused, I've updated my answer to provide a regex, and I'm still getting downvotes.Orchidaceous
@Groome ... and yet he accepted this answer with NO regex. I guess he didn't actaully want the regex after all... he just wanted a simple solution to his problem. Sometimes people think they know the best way to solve a problem... sometimes they need to be shown a better way.Delmydeloach
In C++ getting "bad_brace" error when trying your regexAngell
@MichaelIV, thank you for pointing this out. However, the OP tagged this as JS rather than C++, so...YMMV. ;)Orchidaceous
T
52

Try this:

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

For example

Welcome to RegExr v2.1 by #{gskinner.com},  #{ssd.sd} hosted by Media Temple!

will return gskinner.com, ssd.sd.

Terni answered 30/5, 2017 at 8:52 Comment(5)
Great, can you explain why you use \} in first block?Lucerne
Nice one, but that will match any group that ends with }, even if it doesn't start with {.Oat
This is the only correct answer that actually works.Abdominal
Explanation: While [^\{\}]+ will match anything that is not a curly brace, the lookahead assertion (?=}) will make sure to only pass sections preceding a curly brace. With / ... /g we get all occurrences, not only the first one.Gudrin
if you're going by ERE, then you can just do echo 'apple{ _orange_}}}}}{}}\0304\0226{{{}} tree' | mawk '1; gsub("[^}{]+", " | \"&\" | ")^_' :::::::::::: :::::::::::::: ::::::::::: apple{ _orange_}}}}}{}}Ė{{{}} tree ::::::::::::::::::: :::::::::::::: :::::::::::::::::::: : :::::::: | "apple" | { | " _orange_" | }}}}}{}} | "Ė" | {{{}} | " tree" | to ensure it only grabs the stuff excluding any runs of either curly brace.Benner
C
28

Try this

let path = "/{id}/{name}/{age}";
const paramsPattern = /[^{}]+(?=})/g;
let extractParams = path.match(paramsPattern);
console.log("extractParams", extractParams) // prints all the names between {} = ["id", "name", "age"]
Claudette answered 9/8, 2018 at 9:54 Comment(2)
The exactly what I wanted :) this will return the result without braces, the other solutions return with itSamite
Excellent, the best answer here.Benthos
G
24

Here's a simple solution using javascript replace

var st = '{getThis}';

st = st.replace(/\{|\}/gi,''); // "getThis"

As the accepted answer above points out the original problem is easily solved with substring, but using replace can solve the more complicated use cases

If you have a string like "randomstring999[fieldname]" You use a slightly different pattern to get fieldname

var nameAttr = "randomstring999[fieldname]";

var justName = nameAttr.replace(/.*\[|\]/gi,''); // "fieldname"
Gayton answered 9/8, 2011 at 10:53 Comment(0)
D
18

This one works in Textmate and it matches everything in a CSS file between the curly brackets.

\{(\s*?.*?)*?\}

selector {. . matches here including white space. . .}

If you want to further be able to return the content, then wrap it all in one more set of parentheses like so:

\{((\s*?.*?)*?)\}

and you can access the contents via $1.

This also works for functions, but I haven't tested it with nested curly brackets.

Dash answered 15/12, 2009 at 17:58 Comment(0)
S
17

You want to use regex lookahead and lookbehind. This will give you only what is inside the curly braces:

(?<=\{)(.*?)(?=\})
Setose answered 11/11, 2010 at 12:26 Comment(5)
There should be a backslash escaping the curly braces above. They got stripped out in my submission.Setose
any disadvantages of this method?Clop
@Somatik—yes, negative lookahead and behind are't supported in ECMAScript.Micromillimeter
Note: This example works in Java. Returns all values in all curly braces.Gosh
I wish I could up vote this more since it's the only correct answer on this page.Homogenetic
B
8

i have looked into the other answers, and a vital logic seems to be missing from them . ie, select everything between two CONSECUTIVE brackets,but NOT the brackets

so, here is my answer

\{([^{}]+)\}
Bittner answered 22/6, 2017 at 20:30 Comment(0)
S
6

Regex for getting arrays of string with curly braces enclosed occurs in string, rather than just finding first occurrence.

 /\{([^}]+)\}/gm 
Spindrift answered 23/8, 2016 at 9:13 Comment(0)
R
5

This one matches everything even if it finds multiple closing curly braces in the middle:

\{([\s\S]*)\}

Example:

{
  "foo": {
    "bar": 1,
    "baz": 1,
  }
}
Relict answered 29/1, 2021 at 23:50 Comment(1)
Live saver. Exactly what I just needed. Thanks a millionSpin
S
4
var re = /{(.*)}/;
var m = "{helloworld}".match(re);
if (m != null)
    console.log(m[0].replace(re, '$1'));

The simpler .replace(/.*{(.*)}.*/, '$1') unfortunately returns the entire string if the regex does not match. The above code snippet can more easily detect a match.

Swatter answered 2/11, 2012 at 19:30 Comment(0)
G
4

Try this one, according to http://www.regextester.com it works for js normaly.

([^{]*?)(?=\})

Geomancy answered 23/9, 2016 at 12:17 Comment(1)
for multiple selection you can use /([^{]*?)\w(?=\})/gmiPelligrini
S
2

You can use this regex recursion to match everythin between, even another {} (like a JSON text) :

\{([^()]|())*\}
Sutler answered 6/11, 2017 at 15:25 Comment(2)
Nice, but this only captures the content inside nested bracesJulissa
does not capture if the content contains ()Diploid
A
2

Even this helps me while trying to solve someone's problem,

Split the contents inside curly braces ({}) having a pattern like, {'day': 1, 'count': 100}.

For example:

#include <iostream> 
#include <regex> 
#include<string> 
using namespace std; 

int main() 
{ 
    //string to be searched
    string s = "{'day': 1, 'count': 100}, {'day': 2, 'count': 100}";

    // regex expression for pattern to be searched 
    regex e ("\\{[a-z':, 0-9]+\\}");
    regex_token_iterator<string::iterator> rend;

    regex_token_iterator<string::iterator> a ( s.begin(), s.end(), e );
    while (a!=rend) cout << " [" << *a++ << "]";
    cout << endl;

    return 0; 
}

Output:

[{'day': 1, 'count': 100}] [{'day': 2, 'count': 100}]
Adenocarcinoma answered 30/5, 2020 at 12:20 Comment(0)
B
0
echo '/{id}/{name}/{age}' |
mawk NF=NF FS='(^|[}]+)(/[{]+|$)' OFS='\v'
id
  name
      age

You can extract them out just as easily with the most bland flavor of ERE

Benner answered 10/3, 2023 at 18:25 Comment(0)
O
-1

Your can use String.slice() method.

let str = "{something}";
str = str.slice(1,-1) // something
Ossification answered 24/5, 2022 at 20:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.