Related
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 #
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);
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);
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);
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