RegEx replacing numbers greater than variable in Javascript - javascript

I have the string:
"selection1 selection2 selection3 selection4"
I am looking to remove all words that end in a number greater than a variable. For instance:
let str = "selection1 selection2 selection3 selection4";
let x = 2;
let regExp = RegExp(...);
let filtered = str.replace(regExp , ""); // should equal "selection1 selection2"
I came up with the following expression which selects all words that end in numbers greater than 29:
/(selection[3-9][0-9]|[1-9]\d{3}\d*)/gi
The result from this regEx on the string "selection1 selection 40" is [selection40]
I feel that I'm part of the way there.
Given that I'm dealing with single and double digit numbers and am looking to incorporate a variable, what regEx could help me alter this string?

You can use .replace with a callback:
let str = "selection5 selection1 selection2 selection3 selection4";
let x = 2;
let regex = /\s*\b\w+?(\d+)\b/g;
let m;
let repl = str.replace(regex, function($0, $1) {
return ($1 > x ? "" : $0);
}).trim();
console.log( repl );
Regex /\b\w+?(\d+)\b/g matches all the words ending with 1+ digits and captures digits in capture group #1 which we use inside the callback function to compare against variable x.

You can split by whitespace, then capture the group using Regex which gets the only the numeric part and filter it accordingly.
const str = "selection1 selection2 selection3 selection4";
const threshold = 2;
const pattern = /selection(\d+)/
const result = str
.split(' ')
.filter(x => Number(x.match(pattern)[1]) <= threshold)
.join(' ');
console.log(result);

Related

regex replace for multiple string array javascript

I have a array of string and the patterns like #number-number anywhere inside a string.
Requirements:
If the # and single digit number before by hyphen then replace # and add 0. For example, #162-7878 => 162-7878, #12-4598866 => 12-4598866
If the # and two or more digit number before by hyphen then replace remove #. For example, #1-7878 => 01-7878.
If there is no # and single digit number before by hyphen then add 0. For example, 1-7878 => 01-7878.
I got stuck and how to do in JavaScript. Here is the code I used:
let arrstr=["#12-1676","#02-8989898","#676-98908098","12-232","02-898988","676-98098","2-898988", "380100 6-764","380100 #6-764","380100 #06-764"]
for(let st of arrstr)
console.log(st.replace(/#?(\d)?(\d-)/g ,replacer))
function replacer(match, p1, p2, offset, string){
let replaceSubString = p1 || "0";
replaceSubString += p2;
return replaceSubString;
}
I suggest matching # optionally at the start of string, and then capture one or more digits before - + a digit to later pad those digits with leading zeros and omit the leading # in the result:
st.replace(/#?\b(\d+)(?=-\d)/g, (_,$1) => $1.padStart(2,"0"))
See the JavaScript demo:
let arrstr=["#12-1676","#02-8989898","#676-98908098","12-232","02-898988","676-98098","2-898988", "380100 6-764","380100 #6-764","380100 #06-764"]
for(let st of arrstr)
console.log(st,'=>', st.replace(/#?\b(\d+)(?=-\d)/g, (_,$1) => $1.padStart(2,"0") ))
The /#?\b(\d+)(?=-\d)/g regex matches all occurrences of
#? - an optional # char
\b - word boundary
(\d+) - Capturing group 1: one or more digits...
(?=-\d) - that must be followed with a - and a digit (this is a positive lookahead that only checks if its pattern matches immediately to the right of the current location without actually consuming the matched text).
Using the unary operator, here's a two liner replacer function.
const testValues = ["#162-7878", "#12-4598866", "#1-7878", "1-7878"];
const re = /#?(\d+?)-(\d+)/;
for(const str of testValues) {
console.log(str.replace(re, replacer));
}
function replacer(match, p1, p2) {
p1 = +p1 < 10 ? `0${p1}` : p1;
return `${p1}-${p2}`;
}
let list_of_numbers =["#1-7878", "#162-7878", "#12-1676","#02-8989898","#676-98908098","12-232","02-898988","676-98098","2-898988"]
const solution = () => {
let result = ''
for (let number of list_of_numbers) {
let nums = number.split('-')
if (nums[0][0] == '#' && nums[0].length > 2) {
result = `${nums[0].slice(1, number.length-1)}-${nums[1]}`
console.log(result)
} else if (nums[0][0] == '#' && nums[0].length == 2) {
result = `${nums[0][0] = '0'}${nums[0][1]}-${nums[1]}`
console.log(result)
} else {
console.log(number)
}
}
}
I think a simple check is what you should do with the match function.
let arrstr=["#12-1676","#0-8989898","#676-98908098","12-232","02-898988","676-98098","2-898988"];
const regex = /#\d-/g;
for(i in arrstr){
var found = arrstr[i].match(regex);
if(found){
arrstr[i]=arrstr[i].replace("#","0")
}else{
arrstr[i]=arrstr[i].replace("#","")
}
}
console.log(arrstr);
or if you really want to stick with the way you have it.
let arrstr=["#12-1676","#02-8989898","#6-98908098","12-232","02-898988","676-98098","2-898988"]
for(let st of arrstr)
console.log(st.replace(/#(\d)?(\d-)/g ,replacer))
function replacer(match, p1, p2, offset, string){
let replaceSubString = p1 || "0";
replaceSubString += p2;
return replaceSubString;
}
remove the '?' from the regex so its not #? but just #

Replace 2 characters inside a string in JavaScript

I have this string and I want to fill all the blank values with 0 between to , :
var initialString = 3,816,AAA3,aa,cc,bb,5.9,27,46,0.62,29,12,7,10,13.1,86,6.02,20,1.68,8,0.24,48,22,6.2,0.9,,,1,
I want this output :
var finalString = 3,816,AAA3,aa,cc,bb,5.9,27,46,0.62,29,12,7,10,13.1,86,6.02,20,1.68,8,0.24,48,22,6.2,0.9,0,0,1,0
I try to use replace
var newString = initialString.replace(/,,/g, ",0,").replace(/,$/, ",0");
But the finalString looks like this:
var initialString = 3,816,AAA3,aa,cc,bb,5.9,27,46,0.62,29,12,7,10,13.1,86,6.02,20,1.68,8,0.24,48,22,6.2,0.9,0,,1,0
Some coma are not replaced.
Can someone show me how to do it?
You can match a comma which is followed by either a comma or end of line (using a forward lookahead) and replace it with a comma and a 0:
const initialString = '3,816,AAA3,aa,cc,86,6.02,20,1.68,8,0.24,48,22,6.2,0.9,,,1,';
let result = initialString.replace(/,(?=,|$)/g, ',0');
console.log(result)
using split and join
var str = "3,816,AAA3,aa,cc,bb,5.9,27,46,0.62,29,12,7,10,13.1,86,6.02,20,1.68,8,0.24,48,22,6.2,0.9,,,1,";
const result = str
.split(",")
.map((s) => (s === "" ? "0" : s))
.join(",");
console.log(result);

JavaScript regexp, not getting all matches, what am I missing here? [duplicate]

This question already has answers here:
How can I match overlapping strings with regex?
(6 answers)
Closed 4 years ago.
Let's say for example I have this simple string
let str = '5+81+3+16+42'
Now if I want to capture each plus sign with both numbers around it.
My attempt was as follows:
let matches = str.match(/\d+\+\d+/g);
What I got with that is:
['5+81', '3+16']
Why is it not matching the cases between?
['5+81', '81+3', '3+16', '16+42']
Your regex has to fulfill the whole pattern which is \d+\+\d+. It will first match 5+81, then the next character is a + which the pattern can not match because it should start with a digit. Then it can match 3+16 but it can not match the following +42 anymore given you ['5+81', '3+16'] as the matches.
Without a regex, you might use split and a for loop and check if the next value exists in the parts array:
let str = '5+81+3+16+42'
let parts = str.split('+');
for (let i = 0; i < parts.length; i++) {
if (undefined !== parts[i + 1]) {
console.log(parts[i] + '+' + parts[i + 1]);
}
}
When using more a recent version of Chrome which supports lookbehinds, you might use lookarounds with capturing groups:
(?<=(\d+))(\+)(?=(\d+))
See the regex demo
const regex = /(?<=(\d+))(\+)(?=(\d+))/g;
const str = `5+81+3+16+42`;
let m;
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
console.log(m[1] + m[2] + m[3]);
}
When the regular expression engine completes one iteration of a match, it "consumes" the characters from the source string. The first match of 5+81 leaves the starting point for the next match at the + sign after 81, so the next match for the expression begins at the 3.
Split string by + delimiter and use .reduce() to create new array contain target result.
let str = '5+81+3+16+42';
let arr = str.split('+').reduce((tot, num, i, arr) => {
i+1 < arr.length ? tot.push(num+"+"+arr[i+1]) : '';
return tot;
}, []);
console.log(arr);
You can do it using split and reduce without making things complex with regex.
let str = '5+81+3+16+42';
const array = str.split('+');
const splited = []
array.reduce((a, b) => {
splited.push(a+'+'+b)
return b
})
console.log(splited);

RegEx: different initials format

I am using this piece of code to get the initials of the person's full name:
var name = "John Smith"; // for an example
var initials = name.match(/\b\w/g) || [];
initials = ((initials.shift() || '') + (initials.pop() || '')).toUpperCase();
// initials then returns "JS"
Now I need my initials to return the first letter of the first name and three letters of the last name ("JSMI" in the example above).
What should I alter in my regex in order to do that?
Also, if person would have two names (for example "John Michael Smith"), I need to get "JMSMI" as a result...
Any other solutions are welcome!
Try with Array#split() , substring() and Array#map
first you need split the string with space.
And get the single letter array[n-1] using sustring,
Then get the 3 letter on final argument of array
Map function iterate each word of your string
function reduce(a){
var c= a.split(" ");
var res = c.map((a,b) => b < c.length-1 ? a.substring(0,1) : a.substring(0,3))
return res.join("").toUpperCase()
}
console.log(reduce('John Michael Smith'))
console.log(reduce('John Smith'))
You may add a \b\w{1,3}(?=\w*$) alternative to your existing regex at the start to match 1 to 3 words chars in the last word of the string.
var name = "John Michael Smith"; //John Smith" => JSMI
var res = name.match(/\b\w{1,3}(?=\w*$)|\b\w/g).map(function (x) {return x.toUpperCase()}).join("");
console.log(res);
See the regex demo.
Regex details:
\b - a leading word boundary
\w{1,3} - 1 to 3 word chars (ASCII letters, digits or _)
(?=\w*$) - a positive lookahead requiring 0+ word chars followed with the end of string position
| - or
\b\w - a word char at the start of a word.
I tried to avoid capturing groups (and used the positive lookahead) to make the JS code necessary to post-process the results shorter.
Use split() and substr() to easily do this.
EDIT
Updated code to reflect the middle initial etc
function get_initials(name) {
var parts = name.split(" ");
var initials = "";
for (var i = 0; i < parts.length; i++) {
if (i < (parts.length - 1)) {
initials += parts[i].substr(0, 1);
} else {
initials += parts[i].substr(0, 3);
}
}
return initials.toUpperCase();
}
console.log(get_initials("John Michael Smith"));
My two cents with a reducer :)
function initials(name) {
return name.split(' ').reduce(function(acc, item, index, array) {
var chars = index === array.length - 1 ? 3 : 1;
acc += item.substr(0, chars).toUpperCase();
return acc;
}, '')
}
console.log(initials('John'));
console.log(initials('John Michael'));
console.log(initials('John Michael Smith'));
You may want use String.prototype.replace to drop following letters:
This regexp will match first 1 (or 3 for last name) letters in a word, and only keep it.
'John Smith'.replace(/(?:(\w)\w*\s+)|(?:(\w{3})\w*$)/g, '$1$2').toUpperCase()
const name = "John Michael Smith";
const initials = name.toUpperCase().split(/\s+/)
.map((x, i, arr) => x.substr(0, i === arr.length - 1 ? 3 : 1))
.join('');
console.log(initials);

Javascript SUBSTR

I have a dynamic string value "radio_3_*".
Like:
1 - radio_3_5
2 - radio_3_8
3 - radio_3_78
4 - radio_3_157
5 - radio_3_475
How can I pick the radio_3 part.
Basic regular expression
var str = "radio_3_5";
console.log(str.match(/^[a-z]+_\d+/i));
And how the reg exp works
/ Start of reg exp
^ Match start of line
[a-z]+ Match A thru Z one or more times
_ Match underscore character
\d+ Match any number one or more times
/ End of Reg Exp
i Ignores case
Or with split
var str = "radio_334_1234";
var parts = str.split("_");
var result = parts[0] + "_" + parts[1];
Or even crazier (would not do)
var str = "radio_334_1234";
var result = str.split("_").slice(0,2).join("_");
You could just take your string and use javascript method match
myString = "radio_334_1234"
myString.match("[A-Za-z]*_[0-9]*")
//output: radio_334
[A-Za-z]* Will take any number of characters in upper or lower case
_ Will take the underscore
[0-9]* Will take any number of characters from 0 to 9
Try this:
var str = 'radio_3_78';
var splitStr = str.split('_');
var result = splitStr[0] + '_' + splitStr[1];
http://jsfiddle.net/7faag7ug/2/
Use split and pop, like below.
"radio_3_475".split("_").pop(); // = 475

Categories

Resources