First I think it's worth explaining why your regex didn't work.By default, the https://www.regular-expressions.info/repeat.html (as * and +) are http://rexegg.com/regex-quantifiers.html#greedytrap and try to get as many characters as possible.In your case, regex is \{.*\}, i.e. the character { followed by zero or more characters (.*), followed by }. The point corresponds to https://www.regular-expressions.info/dot.html . And by "any character", understand that it's anyone, including { and } (if regex thinks it is necessary to satisfy the expression, the point can yes catch these characters).So in your case, the regex criteria are: you have a {, followed by several characters (any one, including others { and }, if the regex finds necessary), followed by one }. And what is the biggest string that matches these criteria? The entire string. The passage \{ from regex takes the first character {, .* takes all the other nineteen {, plus the text, plus the nineteen }, and finally \} take the last } ( https://regex101.com/r/YO88cP/1/ ).An alternative to solving has already been given in https://pt.stackoverflow.com/a/429351/112052 : use a quantifier http://rexegg.com/regex-quantifiers.html#lazy_solution , i.e. exchange .* by .*?. This causes regex to take the lowest possible amount of characters, and with that it doesn't take any more { and } than should (to know more about quantifiers Lazy, read https://pt.stackoverflow.com/q/415757/112052 and https://pt.stackoverflow.com/a/401755/112052 ).But it also gives to solve in other ways. The whole problem started because you used the point, which corresponds to any character (anyone, including the own { and }). But you don't want "any character", and yes "anyone who No be it { or }". Therefore, you can use this regex:^\{+(\{[^{}]+\})\}+$
Instead of the point, I used [^{}], which is a https://www.regular-expressions.info/charclass.html#negated . She takes any character No whatever is between [^ and ] (in the case, it is any character other than { neither }). Another detail is that I changed * by +. That's because * means "zero or more characters", i.e. if the text is {{{}}}, the regex finds the passage {}. Already + means "one or more occurrences", so when changing the * by +, I guarantee you must have at least one character between the keys.With this I no longer need the quantifier Lazy, since now there is no risk of taking too many characters - the denied character class ensures that regex will stop as soon as you find the first { or }, which did not occur with the point. That brings small advantage as regex gets faster - compare https://regex101.com/r/uQ3zvM/2 and https://regex101.com/r/JnGO7T/4 and see that the amount of steps decreases more than half (Obviously, for few small strings, the performance difference will be irrelevant - and I admit that in most cases it is just https://stackoverflow.com/a/3471000 - but depending on the size and nature of the texts and the regex used, the indiscriminate use of .* https://www.regular-expressions.info/catastrophic.html ). In any case, there is still another important factor, which is to make your intention clearer: when using .* you understand that anything serves in that passage, already http://rexegg.com/regex-style.html#what_you_want with [^{}], you make it very clear that it is not quite anything you can have there.Finally, I used the https://www.regular-expressions.info/anchors.html ^ and $, which mark respectively the beginning and end of the string. So I guarantee that the string only has what is specified in regex, not an extra character, not at least.Since we talk about being more specific, you can stay changing regex so you have exactly what you need. Use [^{}] is a little better than ., because it restricts the list of possible characters. But [^{}] still accepts many things you may not want, such as special characters, line breaks, emojis, etc. If you want to restrict even more, could use other options. Examples:[a-zA-Z ] - accepts letters from A to Z (maicle and tiny) and spaces (repare that there is a space before the ]). But that doesn't accept sharp letters, so...[\w ] - https://www.regular-expressions.info/shorthand.html \w considers letters, numbers and the character _. And if you activate the flag unicode (in regex101, click the flag which is right side of regex and choose the option u), it also considers accented characters.but if you don't want numbers or characters _, can use [\p{L} ]: the shortcut p{L} considers all letters defined by Unicode (including other alphabets, such as Greek, Japanese, Arabic, Cyrillic, etc.)Anyway, there are many possibilities, and everything will depend on what you need. Does your text only have letters of the Latin alphabet and no accents? Will you also have numbers, scores, etc? Or do you just want anything between the keys? Depending on the tool you use, it may also be that some regex does not work ( JavaScript, for example, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes#Browser_compatibility but you could use [^\W\d_], which has a similar functioning).Balanced keysIt was not clear whether the expression should be balanced (i.e. if each { has one } corresponding). Anyway, below are some options with regex (although this one No be the best tool to check this type of thing - actually I don't think it's the best solution to the original problem, to get the text between the keys, since one loop simple by string would already solve).First the simplest case. If the amount of keys is always the same, you can simply do something like:^\{{19}(\{[^{}]+\})\}{19}$
In the case, \{{19} means "exactly 19 occurrences of the character {", and I did the same for the \}. So I guarantee that the amount of { and } is the same ( https://regex101.com/r/OwfzrV/2 the regex working).Now, if the amount of keys can vary, there is more complicated. The ideal solution is not to use regex, and instead use a programming language to implement some algorithm https://pt.stackoverflow.com/a/354404/112052 .But just as curiosity, it is possible to check this with http://rexegg.com/regex-recursion.html :^(?=(\{([^{}]+|(?1))\})$)\{+(\{[^{}]+\})\}+$
The secret is in the passage (\{((?1)|[^{}]+)\}). First the expression is in brackets, forming a https://www.regular-expressions.info/brackets.html - and as is the first pair of parentheses, then it is group 1.Then we have one https://www.regular-expressions.info/alternation.html (the character | means or), with two possibilities:[^{}]+ - any character other than the keys, or(?1)- that is "the same expression that corresponds to group 1" (the same regex is called here, recursively)That is, this passage can be interpreted as:the character {, followed by:
any character other than the keys, orthe character {, followed by:any character other than the keys, orthe character {, followed by:any character other than the keys, or...the character }the character }the character }With this, regex checks if the keys are balanced. Besides, all the stretch is in one https://www.regular-expressions.info/lookaround.html (between) (?= and )), which serves to verify that something exists ahead (but this something is not part of the match, and I did so because in recursive regex it was not possible to capture the last stretch between keys directly). Soon after lookahead we have the regex we have seen above, to take the desired stretch. https://regex101.com/r/JnGO7T/10 this regex working, and notice that it only catches cases where the keys are balanced. The difference to the previous solutions is that now the stretch you want is in group 3, and no more in group 1.But as I said, I see it more as a curiosity than in fact a practical solution. First because it is too complicated solution for something that can be solved with a simple algorithm, and second because not all languages support recursive regex (which can be considered a positive point, because then you don't even cogitate using them). Regex is cool and I particularly like enough but https://blog.codinghorror.com/regular-expressions-now-you-have-two-problems/ .