Regex to get string between curly braces - javascript

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:
How can one turn regular quotes (i.e. ', ") into LaTeX/TeX quotes (i.e. `', ``'')
Regex: To pull out a sub-string between two tags in a string
Regex to replace all \n in a String, but no those inside [code] [/code] tag

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)

/\{([^}]+)\}/
/ - 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

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

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.

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"]

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"

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.

You want to use regex lookahead and lookbehind. This will give you only what is inside the curly braces:
(?<=\{)(.*?)(?=\})

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
\{([^{}]+)\}

Regex for getting arrays of string with curly braces enclosed occurs in string, rather than just finding first occurrence.
/\{([^}]+)\}/gm

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.

Try this one, according to http://www.regextester.com it works for js normaly.
([^{]*?)(?=\})

This one matches everything even if it finds multiple closing curly braces in the middle:
\{([\s\S]*)\}
Example:
{
"foo": {
"bar": 1,
"baz": 1,
}
}

You can use this regex recursion to match everythin between, even another {} (like a JSON text) :
\{([^()]|())*\}

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}]

Your can use String.slice() method.
let str = "{something}";
str = str.slice(1,-1) // something

Related

Extract content of code which start with a curly bracket and ends with a curly bracket followed by closing parenthesis

I'm completely mess with Regular Expressions right now(lack of practice).
I'm writing a node script, which goes through a bunch of js files, each file calls a function, with one of the arguments being a json. The aim is to get all those json arguments and place them in one file. The problem I'm facing at the moment is the extraction of the argument part of the code, here is the function call part of that string:
$translateProvider.translations('de', {
WASTE_MANAGEMENT: 'Abfallmanagement',
WASTE_TYPE_LIST: 'Abfallarten',
WASTE_ENTRY_LIST: 'Abfalleinträge',
WASTE_TYPE: 'Abfallart',
TREATMENT_TYPE: 'Behandlungsart',
TREATMENT_TYPE_STATUS: 'Status Behandlungsart',
DUPLICATED_TREATMENT_TYPE: 'Doppelte Behandlungsart',
TREATMENT_TYPE_LIST: 'Behandlungsarten',
TREATMENT_TARGET_LIST: 'Ziele Behandlungsarten',
TREATMENT_TARGET_ADD: 'Ziel Behandlungsart hinzufügen',
SITE_TARGET: 'Gebäudeziel',
WASTE_TREATMENT_TYPES: 'Abfallbehandlungsarten',
WASTE_TREATMENT_TARGETS: '{{Abfallbehandlungsziele}}',
WASTE_TREATMENT_TYPES_LIST: '{{Abfallbehandlungsarten}}',
WASTE_TYPE_ADD: 'Abfallart hinzufügen',
UNIT_ADD: 'Einheit hinzufügen'
})
So I'm trying to write a regular expression which matches the segment of the js code, which starts with "'de', {" and ends with "})", while it can have any characters between(single/double curly brackets included).
I tried something like this \'de'\s*,\s*{([^}]*)})\ , but that doesn't work. The furthest I got was with this \'de'\s*,\s*{([^})]*)}\ , but this ends at the first closing curly bracket within the json, which is not what I want.
It seems, that even the concepts of regular exressions I understood before, now I completely forgot.
Any is help is much appreciated.
You did not state the desired output. Here is a solution that parses the text, and creates an array of arrays. You can easily transform that to a desired output.
const input = `$translateProvider.translations('de', {
WASTE_MANAGEMENT: 'Abfallmanagement',
WASTE_TYPE_LIST: 'Abfallarten',
WASTE_ENTRY_LIST: 'Abfalleinträge',
WASTE_TYPE: 'Abfallart',
TREATMENT_TYPE: 'Behandlungsart',
TREATMENT_TYPE_STATUS: 'Status Behandlungsart',
DUPLICATED_TREATMENT_TYPE: 'Doppelte Behandlungsart',
TREATMENT_TYPE_LIST: 'Behandlungsarten',
TREATMENT_TARGET_LIST: 'Ziele Behandlungsarten',
TREATMENT_TARGET_ADD: 'Ziel Behandlungsart hinzufügen',
SITE_TARGET: 'Gebäudeziel',
WASTE_TREATMENT_TYPES: 'Abfallbehandlungsarten',
WASTE_TREATMENT_TARGETS: '{{Abfallbehandlungsziele}}',
WASTE_TREATMENT_TYPES_LIST: '{{Abfallbehandlungsarten}}',
WASTE_TYPE_ADD: 'Abfallart hinzufügen',
UNIT_ADD: 'Einheit hinzufügen'
})`;
const regex1 = /\.translations\([^{]*\{\s+(.*?)\s*\}\)/s;
const regex2 = /',[\r\n]+\s*/;
const regex3 = /: +'/;
let result = [];
let m = input.match(regex1);
if(m) {
result = m[1].split(regex2).map(line => line.split(regex3));
}
console.log(result);
Explanation of regex1:
\.translations\( -- literal .translations(
[^{]* -- anything not {
\{\s+ -- { and all whitespace
(.*?) -- capture group 1 with non-greedy scan up to:
\s*\}\) -- whitespace, followed by })
s flag to make . match newlines
Explanation of regex2:
',[\r\n]+\s* -- ',, followed by newlines and space (to split lines)
Explanation of regex3:
: +' -- literal : ' (to split key/value)
Learn more about regex: https://twiki.org/cgi-bin/view/Codev/TWikiPresentation2018x10x14Regex
This can be done with lookahead, lookbehind, and boundary-type assertions:
/(?<=^\$translateProvider\.translations\('de', {)[\s\S]*(?=}\)$)/
(?<=^\$translateProvider\.translations\('de', {) is a lookbehind assertion that checks for '$translateProvider.translations('de', {' at the beginning of the string.
(?=}\)$) is a lookahead assertion that checks for '})' at the end of the string.
[\s\S]* is a character class that matches any sequence of space and non-space characters between the two assertions.
Here is the regex101 link for you to test
Hope this helps.

Regex to find more than 2 curly braces inside double quotes text

I am trying to find all strings having more than 2 curly braces blocks ie.,
2 dynamic values like {{data1}} {{data2}} between double quotes
Ex:
class="xyz level1 {{disabled}} what is the {{contentStyle}} result"
I tried but no luck
(.*?{{){1,}
Why not \{\{(\w+)?\}\}? This will match the text inside mustache style curly braces.
regexer
I think you're asking for a test of two matches - try String.protoype.match and testing against length
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
function x(str) {
return str.match(/\{\{(\w+)?\}\}/g).length > 1
}
Assuming you actually meant two or more curly braces, you could use the following:
(({){2,})\S*((}){2,})/g
Note, that if you actually want 3 or more curly braces (more than 2, ex {{{code}}}), you can just change the 2s in the example above to 3.
This works by capturing a first group (({){2,}), where ({) matches the open curly bracket, and the {2,} captures two or more of the preceding group. It then allows any number of (the *) non-white-space (the \S) characters, and stops matching when it encounters ((}){2,}), which is the same as what I described for the opening sequence, only with a } instead. The \g is the global flag, allowing it to match multiple instances of the pattern, not just the first.
Use this pattern (\{\{[^}]+\}\})(?!(([^"]*"){2})*[^"]*$) Demo
it will catch inside double quotes only as per title.
This looks a bit hairy but you can do this with the following regex:
let pattern = /([^{}]*\{\{[^{}]+\}\}[^{}]*){2,}/
A few examples:
pattern.test('') // false
pattern.test('{{a}}{{b}}') // true
pattern.test('{{a}}{{fdsa}fdsa}{{4{{3fdsafds42}}fdsafds') // false
You can check the length of your match, this will give you the information about how many 2 curly braces blocks are there:
var p = /(\{\{.+?\}\})/g;
var str = "xyz level1 {{disabled}} what is the {{contentStyle}} result {{what}} is the";
var res = str.match(p); /* here res will either null or an array */
if(res && res.length > 2){
console.log("yes");
}
A simple solution that assumes your braces are always correctly paired:
\w*(?=(\}){2,})

Regular Expression confused by use of double and single quotes

I have this JavaScript (running in Chrome 48.0.2564.103 m):
var s1 = 'label1="abc" label2=\'def\' ';
var s2 = 'label1="abc" label2=\'def\' label3="ghi"';
var re = /\b(\w+)\b=(['"]).*?def.*?\2/;
re.exec(s1); // --> ["label2='def'", "label2", "'"]
re.exec(s2); // --> ["label1="abc" label2='def' label3="", "label1", """]
The first exec() matches label2, as I intended. However, the second gets confused by the double quote after 'label3=' and matches label1 instead.
I had expected the use of .*? to tell the regular expression to make the match as tightly as possible, but clearly it doesn't always. Is there a way to tighten up my regular expression?
Just exclude what was seen as a quote
/\b(\w+)\b=(['"])(?:.(?!\2))*def(?:.(?!\2))*.?\2/
So the change was replacing your .*? with (?:.(?!\2))*.
Break down:
(?!) is negative look ahead, non-capturing
(?:) is non-capturing group.
The last letter right before the closing quote would not match if it's not def, need .? to fix
This allows you to combine other rules when you want to allow a='\'' or a="\"" or further a="\\\"":
/\b(\w+)\b=(['"])(?:\\\\|\\\2|.(?!\2))*def(?:\\\\|\\\2|.(?!\2))*.?\2/
The reason s2 gives a different result is that you add a " on the right side of the "def" after label2, which allows the pattern to correctly match everything between the first and last double quote in the string.
I can only guess that the reason a sparse match (?) doesn't have any effect is that at that point the regex engine has already decided to match " rather than '. Regex does its thing left-to-right after all.
The "simplest" way of solving this is to match only non-quotes, rather than using ., between the quotes:
var re = /\b(\w+)\b=(['"])[^'"]*def[^'"]*\2/;
re.exec(s1); // --> ["label2='def'", "label2", "'"]
re.exec(s2); // --> ["label2='def'", "label2", "'"]
The problem with this is that now you can't put any kind of quotes in the value, even if they are perfectly legal:
// This won't match because of the " after def
var s2 = 'label1="abc" label2=\'def"\' label3="ghi"'
// This won't match because there's an escaped single quote in the value
var s2 = 'label1="abc" label2=\'def\\\'\' label3="ghi"'
But basically, regex isn't made for parsing HTML, so if these limitations are a problem you should look into proper parsing.

Restrict action of toLowerCase to part of a string?

I want to convert most of a string to lower case, except for those characters inside of brackets. After converting everything outside the brackets to lower case, I then want to remove the brackets. So giving {H}ell{o} World as input should give Hello world as output. Removing the brackets is simple, but is there a way to selectively make everything outside the brackets lower case with regular expressions? If there's no simple regex solution, what's the easiest way to do this in javascript?
You can try this:
var str='{H}ell{o} World';
str = str.replace(/{([^}]*)}|[^{]+/g, function (m,p1) {
return (p1)? p1 : m.toLowerCase();} );
console.log(str);
The pattern match:
{([^}]*)} # all that is between curly brackets
# and put the content in the capture group 1
| # OR
[^{]+ # anything until the regex engine meet a {
# since the character class is all characters but {
the callback function has two arguments:
m the complete match
p1 the first capturing group
it returns p1 if p1 is not empty
else the whole match m in lowercase.
Details:
"{H}" p1 contains H (first part of the alternation)
p1 is return as it. Note that since the curly brackets are
not captured, they are not in the result. -->"H"
"ell" (second part of the alternation) p1 is empty, the full match
is returned in lowercase -->"ell"
"{o}" (first part) -->"o"
" World" (second part) -->" world"
I think this is probably what you are looking for:
Change case using Javascript regex
Detect on the first curly brace instead of a hyphen.
Assuming that all parentheses are well balanced, the parts that should be lower cased are contained like this:
Left hand side is either the start of your string or }
Right hand side is either the end of your string or {
This the code that would work:
var str = '{H}ELLO {W}ORLD';
str.replace(/(?:^|})(.*?)(?:$|{)/g, function($0, $1) {
return $1.toLowerCase();
});
// "Hello World"
I would amend #Jack s solution as follows :
var str = '{H}ELLO {W}ORLD';
str = str.replace (/(?:^|\})(.*?)(?:\{|$)/g, function($0, $1) {
return $1.toLowerCase ();
});
Which performs both the lower casing and the bracket removal in one operation!

java script Regular Expressions patterns problem

My problem start with like-
var str='0|31|2|03|.....|4|2007'
str=str.replace(/[^|]\d*[^|]/,'5');
so the output becomes like:"0|5|2|03|....|4|2007" so it replaces 31->5
But this doesn't work for replacing other segments when i change code like this:
str=str.replace(/[^|]{2}\d*[^|]/,'6');
doesn't change 2->6.
What actually i am missing here.Any help?
I think a regular expression is a bad solution for that problem. I'd rather do something like this:
var str = '0|31|2|03|4|2007';
var segments = str.split("|");
segments[1] = "35";
segments[2] = "123";
Can't think of a good way to solve this with a regexp.
Here is a specific regex solution which replaces the number following the first | pipe symbol with the number 5:
var re = /^((?:\d+\|){1})\d+/;
return text.replace(re, '$15');
If you want to replace the digits following the third |, simply change the {1} portion of the regex to {3}
Here is a generalized function that will replace any given number slot (zero-based index), with a specified new number:
function replaceNthNumber(text, n, newnum) {
var re = new RegExp("^((?:\\d+\\|){"+ n +'})\\d+');
return text.replace(re, '$1'+ newnum);
}
Firstly, you don't have to escape | in the character set, because it doesn't have any special meaning in character sets.
Secondly, you don't put quantifiers in character sets.
And finally, to create a global matching expression, you have to use the g flag.
[^\|] means anything but a '|', so in your case it only matches a digit. So it will only match anything with 2 or more digits.
Second you should put the {2} outside of the []-brackets
I'm not sure what you want to achieve here.

Categories

Resources