Getting strings between certain string and a special character - javascript

I am trying to get data between string and special character.
How can I do this in JS?
Below is my code:
var string = '(CATCH: dummy)';
var TitleRegex = /\((CATCH:.*?)\)/;
var titleData = string.match(TitleRegex);
Output should be : dummy

You could possibly fix the current expression by moving the opening ( to the location right after :, /\(CATCH:(.*?)\)/, and then grabbing Group 1 value using something like var titleData = string.match(TitleRegex)[1].
I'd suggest a bit more precise pattern here:
var string = '(CATCH: dummy)';
var TitleRegex = /\(CATCH:\s*([^()]*)\)/;
var titleData = string.match(TitleRegex);
if (titleData) {
console.log(titleData[1]);
}
The regex is \(CATCH:\s*([^()]*)\):
\(CATCH: - a (CATCH: substring
\s* - 0+ whitespaces
([^()]*) - Capturing group 1: any 0 or more chars other than ( and )
\) - a ) char.
You may actually use /\(CATCH:([^()]*)\)/ (without \s*) and just use titleData[1].trim() to get rid of any eventual whitespace on both ends of the required value.

Related

Regex to extract two numbers with spaces from string

I have problem with simple rexex. I have example strings like:
Something1\sth2\n649 sth\n670 sth x
Sth1\n\something2\n42 036 sth\n42 896 sth y
I want to extract these numbers from strings. So From first example I need two groups: 649 and 670. From second example: 42 036 and 42 896. Then I will remove space.
Currently I have something like this:
\d+ ?\d+
But it is not a good solution.
You can use
\n\d+(?: \d+)?
\n - Match new line
\d+ - Match digit from 0 to 9 one or more time
(?: \d+)? - Match space followed by digit one or more time. ( ? makes it optional )
let strs = ["Something1\sth2\n649 sth\n670 sth x","Sth1\n\something2\n42 036 sth\n42 896 sth y"]
let extractNumbers = str => {
return str.match(/\n\d+(?: \d+)?/g).map(m => m.replace(/\s+/g,''))
}
strs.forEach(str=> console.log(extractNumbers(str)))
If you need to remove the spaces. Then the easiest way for you to do this would be to remove the spaces and then scrape the numbers using 2 different regex.
str.replace(/\s+/, '').match(/\\n(\d+)/g)
First you remove spaces using the \s token with a + quantifier using replace.
Then you capture the numbers using \\n(\d+).
The first part of the regex helps us make sure we are not capturing numbers that are not following a new line, using \ to escape the \ from \n.
The second part (\d+) is the actual match group.
var str1 = "Something1\sth2\n649 sth\n670 sth x";
var str2 = "Sth1\n\something2\n42 036 sth\n42 896 sth y";
var reg = /(?<=\n)(\d+)(?: (\d+))?/g;
var d;
while(d = reg.exec(str1)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}
console.log("****************************");
while(d = reg.exec(str2)){
console.log(d[2] ? d[1]+d[2] : d[1]);
}

Regex to validate and extract data from a calculation

I am trying to find out a regular expression where I can validate the input and also extract required information from input.
My input contains a simple calculation like addition, subtraction, multiplication and division.
For example: if input is addtion say 7.01+9.05
var input = '7.01+9.05';
var pattern = /^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$/
var sign;
if (input.match(pattern)) {
var matches = pattern.exec(input);
var left = // logic to extract value 7.01 using matches variable;
var right = // logic to extract value 9.05 using matches variable;
var sing = // logic to extract symbol + using matches variable;
}
I have used the regular expression which I found from this post : Calculator Regular Expression with decimal point and minus sign
Can you please help me how to extract the required data in above code?
In your pattern ^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$ you want to match an optional dot using \d+\.?\d+ which works but now the minimum number of digits to match is 2 due to matching 2 times 1 or more digits using \d+ so 1+1 would not match.
What you could do if it are only simple calculations, you could use 3 capturing groups and match a digit with an optional decimal part using ?\d+(?:\.\d+)?
Your pattern might look like:
^(-?\d+(?:\.\d+)?)([-+*\/])(-?\d+(?:\.\d+)?)$
Explanation
^ Start of string
(-?\d+(?:\.\d+)?) Capture group 1, match 1+ digits with an optional decimal part
([-+*\/]) Capture group 2, match any of the listed in the character class
(-?\d+(?:\.\d+)?) Capture group 2, match 1+ digits with an optional decimal part
$ End of string
See the regex101 demo
For example
var regex = /^(-?\d+(?:\.\d+)?)([-+*\/])(-?\d+(?:\.\d+)?)$/;
[
"21+22",
"7.01+9.05",
"1-1",
"1*1",
"0*1000000",
"8/4"
].forEach(x => {
var res = x.match(regex);
var left = res[1];
var right = res[2];
var sing = res[3];
console.log(left, right, sing);
});
Sure!
You should define capture groups in your regex expression using () and |. It is important define a flag global to your regex to capture all groups.
There are 3 things you need to capture:
the left number -> ^-?\d+\.?\d+
the sign -> [-+*\/]
the right number -> -?\d+\.?\d+$
You should use | alternation to regex use the capturing groups like a or statement beetwen the groups.
The final regex will be:
var pattern = /(^-?\d+\.?\d+)|([-+*\/])|(-?\d+\.?\d+$)/g
The ouput result will be an array where the first position will be the left number, second position the sign and the third position a right number.
Therefore the rest of your code will looks like that:
if (input.match(pattern)) {
var matches = input.match(pattern); \\ I recommend use input.match here too
var left = matches[0];
var right = matches[2];
var sing = matches[1];
}
You can do that using split()
var input = '7.01+9.05';
var pattern = /^-?\d+\.?\d+[-+*\/]-?\d+\.?\d+$/
if (input.match(pattern)) {
var matches = pattern.exec(input)[0].split(/(\+|-|\*|\/)/);
var left = matches[0];
var right = matches[2];
var sign = matches[1];
console.log(left,sign,right);
}

getting values from a string using regular expression

Could anyone help me with this regular expression issue?
expr = /\(\(([^)]+)\)\)/;
input = ((111111111111))
the one I would need to be working is = ((111111111111),(222222222),(333333333333333))
That expression works fine to get 111111 from (input) , but not when there are also the groups 2222... and 3333.... the input might be variable by variable I mean could be ((111111111111)) or the one above or different (always following the same parenthesis pattern though)
Is there any reg expression to extract the values for both cases to an array?
The result I would like to come to is:
[0] = "111111"
[1] = "222222"
[2] = "333333"
Thanks
If you are trying to validate format while extracting desired parts you could use sticky y flag. This flag starts match from beginning and next match from where previous match ends. This approach needs one input string at a time.
Regex:
/^\(\(([^)]+)\)|(?!^)(?:,\(([^)]+)\)|\)$)/yg
Breakdown:
^\(\( Match beginning of input and immedietly ((
( Start of capturing group #1
[^)]+ Match anything but )
)\) End of CG #1, match ) immediately
| Or
(?!^) Next patterns shouldn't start at beginning
(?: Start of non-capturing group
,\(([^)]+)\) Match a separetd group (capture value in CG #2, same pattern as above)
| Or
\)$ Match ) and end of input
) End of group
JS code:
var str = '((111111111111),(222222222),(333333333333333))';
console.log(
str.replace(/^\(\(([^)]+)\)|(?!^)(?:,\(([^)]+)\)|\)$)/yg, '$1$2\n')
.split(/\n/).filter(Boolean)
);
You can replace brackes with , split it with , and then use substring to get the required number of string characters out of it.
input.replace(/\(/g, '').replace(/\)/g, '')
This will replace all the ( and ) and return a string like
111111111111,222222222,333333333333333
Now splitting this string with , will result into an array to what you want
var input = "((111111111111),(222222222),(333333333333333))";
var numbers = input.replace(/\(/g, '').replace(/\)/g, '')
numbers.split(",").map(o=> console.log(o.substring(0,6)))
If the level of nesting is fixed, you can just leave out the outer () from the pattern, and add the left parentheses to the [^)] group:
var expr = /\(([^()]+)\)/g;
var input = '((111111111111),(222222222),(333333333333333))';
var match = null;
while(match = expr.exec(input)) {
console.log(match[1]);
}

How to use a variable inside Regex?

I have this line in my loop:
var regex1 = new RegExp('' + myClass + '[:*].*');
var rule1 = string.match(regex1)
Where "string" is a string of class selectors, for example: .hb-border-top:before, .hb-border-left
and "myClass" is a class: .hb-border-top
As I cycle through strings, i need to match strings that have "myClass" in them, including :before and :hover but not including things like hb-border-top2.
My idea for this regex is to match hb-border-top and then :* to match none or more colons and then the rest of the string.
I need to match:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top
.hb-fill-top:hover
but the above returns only:
.hb-fill-top::before
.hb-fill-top:hover::before
.hb-fill-top:hover
and doesn't return .hb-fill-top itself.
So, it has to match .hb-fill-top itself and then anything that follows as long as it starts with :
EDIT:
Picture below: my strings are the contents of {selectorText}.
A string is either a single class or a class with a pseudo element, or a rule with few clases in it, divided by commas.
each string that contains .hb-fill-top ONLY or .hb-fill-top: + something (hover, after, etc) has to be selected. Class is gonna be in variable "myClass" hence my issue as I can't be too precise.
I understand you want to get any CSS selector name that contains the value anywhere inside and has EITHER : and 0+ chars up to the end of string OR finish right there.
Then, to get matches for the .hb-fill-top value you need a solution like
/\.hb-fill-top(?::.*)?$/
and the following JS code to make it all work:
var key = ".hb-fill-top";
var rx = RegExp(key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "(?::.*)?$");
var ss = ["something.hb-fill-top::before","something2.hb-fill-top:hover::before","something3.hb-fill-top",".hb-fill-top:hover",".hb-fill-top2:hover",".hb-fill-top-2:hover",".hb-fill-top-bg-br"];
var res = ss.filter(x => rx.test(x));
console.log(res);
Note that .replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') code is necessary to escape the . that is a special regex metacharacter that matches any char but a line break char. See Is there a RegExp.escape function in Javascript?.
The ^ matches the start of a string.
(?::.*)?$ will match:
(?::.*)?$ - an optional (due to the last ? quantifier that matches 1 or 0 occurrences of the quantified subpattern) sequence ((?:...)? is a non-capturing group) of a
: - a colon
.* - any 0+ chars other than line break chars
$ - end of the string.
var regex1 = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`)
var passes = [
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top',
'.hb-fill-top:hover',
'.hb-fill-top::before',
'.hb-fill-top:hover::before',
'.hb-fill-top:hover'
];
var fails = ['.hb-fill-top-bg-br'];
var myClass = '.hb-fill-top';
var regex = new RegExp(`^\\${myClass}(:{1,2}\\w+)*$`);
passes.forEach(p => console.log(regex.test(p)));
console.log('---');
fails.forEach(f => console.log(regex.test(f)));
var regex1 = new RegExp('\\' + myClass + '(?::[^\s]*)?');
var rule1 = string.match(regex1)
This regex select my class, and everething after if it start with : and stop when it meets a whitespace character.
See the regex in action.
Notice also that I added '\\' at the beginning. This is in order to escape the dot in your className. Otherwise it would have matched something else like
ahb-fill-top
.some-other-hb-fill-top
Also be careful about .* it may match something else after (I don't know your set of strings). You might want to be more precise with :{1,2}[\w-()]+ in the last group. So:
var regex1 = new RegExp('\\' + myClass + '(?::{1,2}[\w-()]+)?');

Regexp, capture between parentheses, javascript

I have regexp that extracts values between parentheses.
It's working most of the time but not when it ends with a parentheses
var val = 'STR("ABC(t)")';
var regExp = /\(([^)]+)\)/;.
var matches = regExp.exec(val);
​
console.log(matches[1]); //"ABC(t"
What I want is "ABC(t)".
Any ideas how I can modify my regexp to Achive this?
Update
The value is always inside the parentheses.
Some examples:
'ASD("123")'; => '123'
'ASD(123)'; => '123'
'ASD(aa(10)asda(459))'; => 'aa(10)asda(459)'
So first there is some text (always text). Then there is a (, and it always ends with a ). I want the value between.
You may use greedy dot matching inside Group 1 pattern: /\((.+)\)/. It will match the first (, then any 1+ chars other than linebreak symbols and then the last ) in the line.
var vals = ['STR("ABC(t)")', 'ASD("123")', 'ASD(123)', 'ASD(aa(10)asda(459))'];
var regExp = /\((.+)\)/;
for (var val of vals) {
var matches = regExp.exec(val);
console.log(val, "=>", matches[1]);
}
Answering the comment: If the texts to extract must be inside nested balanced parentheses, either a small parsing code, or XRegExp#matchRecursive can help. Since there are lots of parsing codes around on SO, I will provide XRegExp example:
var str = 'some text (num(10a ) ss) STR("ABC(t)")';
var res = XRegExp.matchRecursive(str, '\\(', '\\)', 'g');
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/2.0.0/xregexp-all-min.js"></script>

Categories