129

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:

benomatis
  • 5,035
  • 7
  • 30
  • 51
ChrisInCambo
  • 7,767
  • 15
  • 47
  • 63

15 Answers15

258

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)

Paul Dixon
  • 277,937
  • 48
  • 303
  • 335
  • 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) – Igor May 26 '13 at 17:22
  • 4
    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? – Reality-Torrent Jan 19 '16 at 12:40
  • The parentheses capture the chars between the curly brackets. – Paul Dixon Jan 19 '16 at 21:16
  • 1
    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 too – drevicko Feb 10 '16 at 12:26
  • So how would that be for any number of repetitions? This only matches the first one. – Pier Jul 03 '16 at 17:06
  • 3
    Adding a `g` at the end makes it a global search. See a [working example](http://scriptular.com/#%7B%7B(.*%3F)%7D%7D%7C%7C%7C%7Cg%7C%7C%7C%7C%5B%22hello%20%7B%7B3%7D%7D%20and%20another%20%7B%7B3%7D%7D%22%5D) – Benjamin Jul 05 '16 at 15:56
  • +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... – fpierrat Dec 07 '16 at 08:27
  • 1
    @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 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match – frank Jul 23 '19 at 20:39
153
/\{([^}]+)\}/

/        - 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
meouw
  • 40,162
  • 10
  • 48
  • 67
  • @meouw sa = s.split("/\{([^}]+)\}/"); gives a compile error. illegal repetition, invalid escape character. – likejudo Dec 26 '12 at 00:22
  • @Anil you appear to be using a string as your split argument rather than a regular expression. What are you trying to do? – meouw Dec 26 '12 at 22:09
52

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
Kev
  • 14,115
  • 14
  • 75
  • 106
  • not to be nitpicky but shouldnt the code be g.substring(1,g.length-2) – almog.ori Jun 09 '09 at 13:10
  • 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.) – Kev Jun 09 '09 at 18:06
  • 7
    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. – jvenema Jan 26 '10 at 00:55
  • 2
    ...and Python just has slicing, which IMO is better than anything else :p. – Grant Paul Mar 03 '10 at 06:25
  • 28
    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.. – baash05 Nov 30 '11 at 00:04
  • 5
    @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. – Kev Dec 07 '11 at 16:50
  • @Darron thanks for your encouragement. Whenever I get a downvote on this I get to read your comment first. :) – Kev Apr 02 '14 at 19:52
  • 2
    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. – shadyyx Jul 04 '14 at 08:14
  • 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. – mopsyd Feb 19 '19 at 13:28
  • @mopsyd 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? – Kev Feb 20 '19 at 06:38
  • @Kev 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. – mopsyd Feb 20 '19 at 21:39
  • @mopsyd 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. – Kev Feb 21 '19 at 07:21
  • He asked for a regex, it’s right in the title. The downvote stands, get over it. – mopsyd Jul 19 '19 at 17:32
  • OK now I'm really confused, I've updated my answer to provide a regex, and I'm still getting downvotes. – Kev Jul 17 '20 at 12:40
37

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.

Manfred Radlwimmer
  • 12,469
  • 13
  • 47
  • 56
  • 1
    Great, can you explain why you use `\}` in first block? – Uzair Ali Apr 04 '18 at 13:35
  • 1
    Nice one, but that will match any group that ends with `}`, even if it doesn't start with `{`. – Ahmad Ibrahim May 21 '18 at 16:28
  • 2
    This is the only correct answer that actually works. – pldg Jul 02 '18 at 13:26
  • 1
    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. – 0-_-0 Nov 30 '19 at 20:45
21

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"
chim
  • 7,655
  • 3
  • 44
  • 58
17

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.

Alex Kessaris
  • 179
  • 1
  • 2
17

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"]
Hemadri Dasari
  • 23,970
  • 25
  • 87
  • 133
14

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

(?<=\{)(.*?)(?=\})
Albin
  • 3,990
  • 1
  • 25
  • 19
Robert Cesaric
  • 173
  • 1
  • 2
4

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

 /\{([^}]+)\}/gm 
vusan
  • 4,634
  • 4
  • 36
  • 76
Er. Mohit Agrawal
  • 1,738
  • 12
  • 13
4

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

\{([^{}]+)\}
souparno majumder
  • 1,521
  • 1
  • 21
  • 39
3
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.

Curtis Yallop
  • 5,490
  • 3
  • 37
  • 27
3

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

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

2

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

\{([^()]|())*\}
p3quod
  • 649
  • 8
  • 11
1

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}]
Shudipta Sharma
  • 3,469
  • 1
  • 13
  • 26
0

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

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

Example:

{
  "foo": {
    "bar": 1,
    "baz": 1,
  }
}
Renato
  • 313
  • 3
  • 8