Javascript string match specific regex - javascript

I want to match specific string from this variable.
var string = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64';
Here is my regex :
var string = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64';
var match_data = [];
match_data = string.match(/[0-9]+(?:((\s*\-\s*|\s*\*\s*)[0-9]+)*)\s*\=\s*[0-9]+(?:(\s*\+\s*[0-9]+(?:((\s*\-\s*|\s*\*\s*)[0-9]+)*)\s*=\s*[0-9]+)*)/g);
console.log(match_data);
The output will show
[
0: "150-50-30-20=50"
1: "50-20-10-5=15+1*2*3*4=24+50-50*30*20=0"
2: "2*4*8=64"
]
The result that I want to match from string variable is only
[
0: "150-50-30-20=50"
1: "1*2*3*4=24"
2: "50-50*30*20=0"
]

You may use ((?:\+|^)skip)? capturing group before (\d+(?:\s*[-*\/+]\s*\d+)*\s*=\s*\d+) in the pattern, find each match, and whenever Group 1 is not undefined, skip (or omit) that match, else, grab Group 2 value.
var string = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64',
reg = /((?:^|\+)skip)?(\d+(?:\s*[-*\/+]\s*\d+)*\s*=\s*\d+)/gi,
match_data = [],
m;
while(m=reg.exec(string)) {
if (!m[1]) {
match_data.push(m[2]);
}
}
console.log(match_data);
Note that I added / and + operators ([-*\/+]) to the pattern.
Regex details
((?:^|\+)skip)? - Group 1 (optional): 1 or 0 occurrences of +skip or skip at the start of a string
(\d+(?:\s*[-*\/+]\s*\d+)*\s*=\s*\d+) - Group 2:
\d+ - 1+ digits
(?:\s*[-*\/+]\s*\d+)* - zero or more repetitions of
\s*[-*\/+]\s* - -, *, /, + enclosed with 0+ whitespaces
\d+ - 1+ digits
\s*=\s* - = enclosed with 0+ whitespaces
\d+ - 1+ digits.

As per your input string and the expected results in array, you can just split your string with + and then filter out strings starting with skip and get your intended matches in your array.
const s = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64'
console.log(s.split(/\+/).filter(x => !x.startsWith("skip")))
There are other similar approaches using regex that I can suggest, but the approach mentioned above using split seems simple and good enough.

try
var t = string.split('+skip');
var tt= t[1].split('+');
var r = [t[0],tt[1],tt[2]]
var string = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64';
var t = string.split('+skip');
var tt= t[1].split('+');
var r = [t[0],tt[1],tt[2]]
console.log(r)

const string = '150-50-30-20=50+skip50-20-10-5=15+1*2*3*4=24+50-50*30*20=0+skip2*4*8=64';
const stepOne = string.replace(/skip[^=]*=\d+./g, "")
const stepTwo = stepOne.replace(/\+$/, "")
const result = stepTwo.split("+")
console.log(result)

Related

Regex expression to get numbers without parentheses ()

I'm trying to create a regex that will select the numbers/numbers with commas(if easier, can trim commas later) that do not have a parentheses after and not the numbers inside the parentheses should not be selected either.
Used with the JavaScript's String.match method
Example strings
9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
What i have so far:
/((^\d+[^\(])|(,\d+,)|(,*\d+$))/gm
I tried this in regex101 and underlined the numbers i would like to match and x on the one that should not.
You could start with a substitution to remove all the unwanted parts:
/\d*\(.*?\),?//gm
Demo
This leaves you with
5,10
10,2,5,
10,7,2,4
which makes the matching pretty straight forward:
/(\d+)/gm
If you want it as a single match expression you could use a negative lookbehind:
/(?<!\([\d,]*)(\d+)(?:,|$)/gm
Demo - and here's the same matching expression as a runnable javascript (skeleton code borrowed from Wiktor's answer):
const text = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4`;
const matches = Array.from(text.matchAll(/(?<!\([\d,]*)(\d+)(?:,|$)/gm), x=>x[1])
console.log(matches);
Here, I'd recommend the so-called "best regex trick ever": just match what you do not need (negative contexts) and then match and capture what you need, and grab the captured items only.
If you want to match integer numbers that are not matched with \d+\([^()]*\) pattern (a number followed with a parenthetical substring), you can match this pattern or match and capture the \d+, one or more digit matching pattern, and then simply grab Group 1 values from matches:
const text = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4`;
const matches = Array.from(text.matchAll(/\d+\([^()]*\)|(\d+)/g), x=> x[1] ?? "").filter(Boolean)
console.log(matches);
Details:
text.matchAll(/\d+\([^()]*\)|(\d+)/g) - matches one or more digits (\d+) + ( (with \() + any zero or more chars other than ( and ) (with [^()]*) + \) (see \)), or (|) one or more digits captured into Group 1 ((\d+))
Array.from(..., x=> x[1] ?? "") - gets Group 1 value, or, if not assigned, just adds an empty string
.filter(Boolean) - removes empty strings.
Using several replacement regexes
var textA = `9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
`
console.log('A', textA)
var textB = textA.replace(/\(.*?\),?/g, ';')
console.log('B', textB)
var textC = textB.replace(/^\d+|\d+$|\d*;\d*/gm, '')
console.log('C', textC)
var textD = textC.replace(/,+/g, ' ').trim(',')
console.log('D', textD)
With a loop
Here is a solution which splits the lines on comma and loops over the pieces:
var inside = false;
var result = [];
`9(296,178),5,3(123),10
10,9(296,178),2,5,3(123),3(124,125)
10,7,5(296,293,444,1255),3(218),2,4
`.split("\n").map(line => {
let pieceArray = line.split(",")
pieceArray.forEach((piece, k) => {
if (piece.includes('(')) {
inside = true
} else if (piece.includes(')')) {
inside = false
} else if (!inside && k > 0 && k < pieceArray.length-1 && !pieceArray[k-1].includes(')')) {
result.push(piece)
}
})
})
console.log(result)
It does print the expected result: ["5", "7"]

Getting the content between two characters

So I have this (example) string: 1234VAR239582358X
And I want to get what's in between VAR and X. I can easily replace it using .replace(/VAR.*X/, "replacement");
But, how would I get the /VAR.*X/as a variable?
I think what you are looking for might be
string.match(/VAR(.*)X/)[1]
The brackets around the .* mark a group. Those groups are returned inside the Array that match creates :)
If you want to only replace what's in between "VAR" and "X" it would be
string.replace(/VAR(.*)X/, "VAR" + "replacement" + "X");
Or more generic:
string.replace(/(VAR).*(X)/, "$1replacement$2");
You can try use the RegExp class, new RegExp(`${VAR}.*X`)
You can store it as variable like this,
const pattern = "VAR.*X";
const reg = new RegExp(pattern);
Then use,
.replace(reg, "replacement");
If you
want to get what's in between VAR and X
then using .* would do the job for the given example string.
But note that is will match until the end of the string, and then backtrack to the first occurrence of X it can match, being the last occurrence of the X char in the string and possible match too much.
If you want to match only the digits, you can match 1+ digits in a capture group using VAR(\d+)X
const regex = /VAR(\d+)X/;
const str = "1234VAR239582358X";
const m = str.match(regex);
if (m) {
let myVariable = m[1];
console.log(myVariable);
}
Or you can match until the first occurrence of an X char using a negated character class VAR([^\r\nX]+)X
const regex = /VAR([^\r\nX]+)X/;
const str = "1234VAR239582358X";
const m = str.match(regex);
if (m) {
let myVariable = m[1];
console.log(myVariable);
}

regular expression replacement in JavaScript with some part remaining intact

I need to parse a string that comes like this:
-38419-indices-foo-7119-attributes-10073-bar
Where there are numbers followed by one or more words all joined by dashes. I need to get this:
[
0 => '38419-indices-foo',
1 => '7119-attributes',
2 => '10073-bar',
]
I had thought of attempting to replace only the dash before a number with a : and then using .split(':') - how would I do this? I don't want to replace the other dashes.
Imo, the pattern is straight-forward:
\d+\D+
To even get rid of the trailing -, you could go for
(\d+\D+)(?:-|$)
Or
\d+(?:(?!-\d|$).)+
You can see it here:
var myString = "-38419-indices-foo-7119-attributes-10073-bar";
var myRegexp = /(\d+\D+)(?:-|$)/g;
var result = [];
match = myRegexp.exec(myString);
while (match != null) {
// matched text: match[0]
// match start: match.index
// capturing group n: match[n]
result.push(match[1]);
match = myRegexp.exec(myString);
}
console.log(result);
// alternative 2
let alternative_results = myString.match(/\d+(?:(?!-\d|$).)+/g);
console.log(alternative_results);
Or a demo on regex101.com.
Logic
lazy matching using quantifier .*?
Regex
.*?((\d+)\D*)(?!-)
https://regex101.com/r/WeTzF0/1
Test string
-38419-indices-foo-7119-attributes-10073-bar-333333-dfdfdfdf-dfdfdfdf-dfdfdfdfdfdf-123232323-dfsdfsfsdfdf
Matches
Further steps
You need to split from the matches and insert into your desired array.

Replace all letters which is not between square bracket in Javascript

I need to replace all letter by "a" in string which is not between square brackets in javascript.
let value = "foo[bar9]12a";
// should be replaced by "aaa[bar9]12a"
let value = "[foo]bar5[foo]";
// should be replaced by "[foo]aaa5[foo]"
I tried with regex but it doesn't work like expected:
const value = "foo[bar9]12a";
const alphaRegex = /(?:[\d*]|\[.*\])|(([a-zA-Z]))/gmi;
const result = value.replace(alphaRegex, 'a');
// result = "aaaaaa";
Any suggestions ?
You may use
const value = "foo[bar9]12a";
const rx = /(\[[^\][]*])|[a-z]/gi;
const result = value.replace(rx, function($0, $1) { return $1 || 'a'; });
console.log(result);
The /(\[[^\][]*])|[a-z]/gi regex matches all occurrences (in a case insensitive way) of
(\[[^\][]*]) - Capturing group 1: [, 0+ chars other than [ and ] and then a ]
| - or
[a-z] - an ASCII letter.
If Group 1 matched, the return value is the captured substring, else, a.
One option is to match a non-bracket character, then lookahead for non-bracket characters eventually followed by a [ or the end of the string:
const value = "foo[bar9]12a";
console.log(
value.replace(/[^[\]](?=[^[\]]*(?:\[|$))/g, 'a')
);

Javascript Regex: Capture between two asterisks with multiple asterisks in comma delimited string

I am trying to capture all characters between multiple instances of asterisks, which are comma delimited in a string. Here's an example of the string:
checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*
The caveat is that the phrase must start and end with an asterisk. I have been able to come close by using the following regex, however, it won't discard any matches when the captured string is missing the starting asterisk(*):
let str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*"
const regex = /[^\,\*]+(?=\*)/gi;
var a = str.match(regex)
console.log(a) // answer should exclude checkboxID0 and checkboxID5
The answer returns the following, however, "checkboxID0 and checkboxID5" should be excluded as it doesn't start with an asterisk.
[
"checkboxID0",
"checkboxID1",
"checkboxID3",
"checkboxID5"
]
Thanks, in advance!
You need to use asterisks on both ends of the pattern and capture all 1 or more chars other than commas and asterisks in between:
/\*([^,*]+)\*/g
See the regex demo
Pattern details
\* - an asterisk
([^,*]+) - Capturing group 1: one or more chars other than , and *
\* - an asterisk
JS demo:
var regex = /\*([^,*]+)\*/g;
var str = "checkboxID0*,*checkboxID1*,&checkboxID2&,*checkboxID3*,!checkboxID4!,checkboxID5*";
var m, res = [];
while (m = regex.exec(str)) {
res.push(m[1]);
}
console.log(res);

Categories