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"]
i have a string that i want to find "a" character and first "c" character and replace with "*" character, but regular expression find all "a" and "c" character i don't know how do it.
here my code:
var pattern=/[a][c]/g; //here my pattern
var str1="aaaaaaaaaabbbbbbaaaaaaaaaabbbccccccccccbbbbbbbbccc";
var rep=str1.replace(pattern,"*");
$("p").html(rep);
You can use capture groups for all a or c sequences but the 1st, and replace them with '*$1' ($1 is the replacement pattern for the capture group):
const str = `aaaaaaaaaabbbbbbaaaaaaaaaabbbccccccccccbbbbbbbbccc`;
const result = str.replace(/[ac]([ac]+)/g, '*$1');
console.log(result);
You need two replacements, because a single one replaces either a or c, depending on the first occurence in the string.
var string = "aaaaaaaaaabbbbbbaaaaaaaaaabbbccccccccccbbbbbbbbccc",
result = string
.replace(/a/, '*')
.replace(/c/, '*');
console.log(result);
An approach with a single replace and a closure over a hash table.
var string = "aaaaaaaaaabbbbbbaaaaaaaaaabbbccccccccccbbbbbbbbccc",
result = string.replace(/[ac]/g, (h => c => h[c] ? c : (h[c] = '*'))({}));
console.log(result);
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)
I want to replace a character but nothing happens.
const str = '//id//user/param//test';
const result = str.replace(/[//]/gi, '/');
This is what i get :
//id//user/param//test
This is what i want :
/id/user/param/test
[...] denotes a character group, which matches any one of these characters. So, [//] essentially means "match / or /". Thus [//] is the same as [/].
You don't want a character group:
const str = '//id//user/param//test';
console.log(str.replace(/\/\//gi, '/'));
If you want to match two or more /, use the + or {2,} quantifiers:
/\/{2,}/
/\/\/+/
You can do it also using a regex group /\/+/
const str = '//id//user/param//test';
const result = str.replace(/\/+/g, '/')
console.log(result)
I'm trying to find all the matches for 'test' in my string:
const search = "test";
const regexString = "(?:[^ ]+ ){0,3}" + "test" + "(?: [^ ]+){0,3}";
const re = new RegExp(regexString, "gi");
const matches = [];
const fullText = "my test string with a lot of tests that should match the test regex";
let match = re.exec(fullText);
while (match != undefined) {
matches.push(match[1]);
match = re.exec(fullText);
}
console.log(matches);
I'm getting the following:
[ undefined, undefined, undefined ]
Why isn't my search working?
Your code expects the result of the match to include stuff captured in capturing groups in the regular expression. However, your regular expression contains only non-capturing groups. The (?: ) grouping explicitly does not capture the matched substring.
You want plain ( ) groupings.
You should enclose your non-capturing groups (?:...) in a capturing group (...) since you are invoking a capturing group (match[1]). :
"((?:\\S+ ){0,3})" + search + "((?: \\S+){0,3})"
Trying to return an array containing the 3 words preceding and
proceeding 'test'
Then you need to push both captured groups not one:
matches.push([match[1], search, match[2]]);
// `match[1]` refers to first capturing group
// `match[2]` refers to second CG
// `search` contains search word
JS code:
const search = "test";
const regexString = "((?:\\S+ ){0,3})" + search + "((?: \\S+){0,3})";
const re = new RegExp(regexString, "gi");
const matches = [];
const fullText = "my test string with a lot of tests that should match the test regex";
while ((match = re.exec(fullText)) != null) {
matches.push([match[1], search, match[2]]);
}
console.log(matches);