Adding a whitespace in front of the first number in a string - javascript

I need a whitespace to be added in front of the first number of a string, unless there is one already and unless the number is the first character in the string.
So I wrote this JS code:
document.getElementById('billing:street1').addEventListener('blur', function() {
var value = document.getElementById('billing:street1').value;
var array = value.match(/\d{1,}/g);
if (array !== null) {
var number = array[0];
var index = value.indexOf(number);
if(index !== 0){
var street = value.substring(0, index);
var housenumber = value.substring(index);
if (street[street.length - 1] !== ' ') {
document.getElementById('billing:street1').value = street + ' ' + housenumber;
}
}
}
});
Fiddle
It works fine, but I feel like this can probably be done in a smarter, more compact way.
Also, JQuery suggestions welcome, I am just not very familiar with it.

Try this one :
const addSpace = (str) => {
return str.replace(/(\D)(\d)/, "$1 $2")
}
console.log(addSpace("12345")) // "12345"
console.log(addSpace("city12345")) // "city 12345"
console.log(addSpace("city")) // "city"
(\D) captures a non-digit
(\d) captures a digit
so (\D)(\d) means : non-digit followed by a digit
that we replace with "$1 $2" = captured1 + space + captured2

You can do it by using only regular expressions. For example:
var s = "abcde45";
if(!s.match(/\s\d/)){
s = s.replace(/(\d)/, ' $1');
}
console.log(s); // "abcde 45"
UPD : Of course, if you have string with a wrong syntax(e.g no numbers inside), that code wouldn't work.

Related

How to remove delimiters from a given RegEx?

my input:
str = "User-123"
o/p:
name: User
id: 123
another input:
str = "User 123"// current this works with my regex.
o/p: As above
other possible inputs:
str = "User:123"
str = "User/123"
str = "User:123"
code:
let m = value.match(/([a-z]+\s*\d+)\s+([a-z]+\s*\d+|\d+\s*[a-z]+)/i);
if (m) {return true}
else {return false}
if I have delimiters the above code return false as it does not find the match for the delimiters. I want to return true for all the scenarios listed above.
currently it removes only the whitespaces, how can I remove delimiters from this regex as well?
It looks like you just want to split on a non-alphanumeric character:
let inputs = [
"User:123",
"User/123",
"User:123",
"User-123",
"User 123"
]
for (i of inputs){
let [name, id] = i.split(/[^a-z0-9]/i)
console.log("name:", name, "id:", id)
}
You might consider simplifying your expression. Using capturing groups, you can simply add/remove any delimiters that you wish. For instance, this expression shows how you might use capturing group:
([A-z]+)(:|\/)([0-9]+)
Graph
This graph shows how the expression work:
Code
This code shows how to do so and does a basic benchmark with 1 million times repeat.
repeat = 1000000;
start = Date.now();
for (var i = repeat; i >= 0; i--) {
var string = 'User/123';
var regex = /([A-z]+)(:|\/)([0-9]+)/g;
var match = string.replace(regex, "$1$3");
}
end = Date.now() - start;
console.log(match + " is a match 💚 ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. 😳 ");

Finding the index to a non-specified character

Let's say for example I have a string
thisIsThisTuesday Day
I want to find the index of all the capital letters, test if there is a space before it, and if not insert one. I would need the index of each one.
At least from what I can see indexOf(String) will only produce the index of the first occurance of the character T/t
This :
for(i=0;i<str.length;i++){
let char=str[i];
if(isNaN(char*1)&&char==char.toUpperCase()){
y=str.indexOf(char);
console.log(char,y)
}
}
would produce the capital letters, and their indexes but will only display the first occurrence of the character in question. I feel pretty confident that the part I am missing is a for() loop in order to move the index iteration..but it escapes me.
Thank you in advance!
You can use a regex:
It matches any non-whitespace character followed by a capital letter and replaces it by the two characters with a space between.
const str = "thisIsThisTuesday Day";
const newstr = str.replace(/([^ ])([A-Z])/g, "$1 $2");
console.log(newstr);
You can use the following regular expression:
/(?<=\S)(?=[A-Z])/g
The replace will insert spaced between characters which are non-space followed by a capital letter.
See example below:
let str = "thisIsThisTuesday Day";
const res = str.replace(/(?<=\S)(?=[A-Z])/g, ' ');
console.log(res);
Note: As pointed out ?<= (positive lookbehind) is currently not be available in all browsers.
Actually, the String.indexOf function can take a second argument, specifying the character it should start searching from. Take a look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
But, if you just want to find all capital letters and prefix them with a space character, if one is not found, there are many approaches, for example:
var str = "thisIsThisTuesday Day";
var ret = '';
for (var i=0; i<str.length; i++) {
if (str.substr(i, 1) == str.substr(i, 1).toUpperCase()) {
if ((i > 0) && (str.substr(i - 1,1) != " "))
ret += " ";
}
ret += str.substr(i,1);
}
After running this, ret will hold the value "this Is This Tuesday Day"
You could iterate over the string and check if each character is a capital. Something like this:
const s = 'thisIsThisTuesday Day';
const format = (s) => {
let string = '';
for (let c of s) {
if (c.match(/[A-Z]/)) string += ' ';
string += c;
}
return string;
};
console.log(format(s));
Or alternatively with reduce function:
const s = 'thisIsThisTuesday Day';
const format = (s) => s.split('').reduce((acc, c) => c.match(/[A-Z]/) ? acc + ` ${c}` : acc + c, '');
console.log(format(s));

Extracting substring based on a single or double digit character using javascript

This is a new question based on my previously asked question Extracting substring from string based on delimiter (answer accepted)
I have a string ]d1[)½}06~9N110375286414~1T12345ABCD~D150600~S12345ABCDEF98765}
Note: There is a space after } in the above example
My delimiters on the above strings are 9N, 1T, D, S and I need to extract the substrings after the delimiter until it hits ~ or EOL.
In the fiddle below it is expecting D1 and S1 as the delimiters instead of D and S respectively.
I am facing 2 problems
1) Single char delimiter issue (D, S)
2) How should I strip off } at the end of the string when returning values. For example, the substring with delimiter S should return 12345ABCDEF98765 instead of 12345ABCDEF98765}
Fiddle (Results are console based)
JS
// Use ]d1[)½}06~9N110375286414~1T12345ABCD~D150600~S12345ABCDEF98765}
// Note: There is an empty space after the } char as shown above
var dataNames = {
'9N': 'PPN',
'1T': 'batchNumber',
'D': 'expireDate',
'S': 'serialNumber'
};
var input = document.querySelector("input");
document.querySelector("button").addEventListener("click", function() {
var str = input.value;
console.log(parseGS1(str));
});
function parseGS1(str) {
var fnc1 = "~";
var data = {};
//remove ]d1[)½}06~
str = str.slice(10);
while (str.length) {
//get the AI identifier: 1T, 9N etc
let aiIdent = str.slice(0, 2);
//get the name we want to use for the data object
let dataName = dataNames[aiIdent];
//update the string
str = str.slice(2);
switch (aiIdent) {
case "1T":
case "9N":
let fnc1Index = str.indexOf(fnc1);
//eol or fnc1 cases
if (fnc1Index == -1) {
data[dataName] = str.slice(0);
str = "";
} else {
data[dataName] = str.slice(0, fnc1Index);
str = str.slice(fnc1Index + 1);
}
break;
case "D":
case "S":
//eol or fnc1 cases
break;
default:
console.log("unexpected ident encountered:", aiIdent);
return false;
break;
}
}
return data;
}
You could also do this using a regex. With this solution it will still work when parts of the string are moved around.
function getData(input) {
input = input.slice(0, input.length - 2);
// The regex has two capture groups.
// Group 1 gets the identifier, this can also be the start of the string.
// Group 2 gets all the characters between the identifier and the '~' char or '} '.
// The third group is a non-capturing group, it is used to find the delimiter where the next part starts.
var
regex = /(^|9N|1T|D|S)(.*?)(?:~|$)/g,
data = {},
match = regex.exec(input);
while (match !== null) {
switch(match[1]) {
case '9N':
data.PPN = match[2];
break;
case '1T':
data.batch = match[2];
break;
case 'D':
data.expireDate = match[2];
break;
case 'S':
data.serial = match[2];
break;
}
var msg = 'Found ' + match[0] + ' / identifier = ' + match[1] + ' / value = ' + match[2] + '. ';
console.log(msg);
// Get the next match.
match = regex.exec(input);
}
return data;
}
var input = ']d1[)½}06~9N110375286414~1T12345ABCD~D150600~S12345ABCDEF98765} ',
input2 = ']d1[)½}06~9N110375286414~D150600~1T12345ABCD~S12345ABCDEF98765} ';
console.log(getData(input));
console.log(getData(input2));
In your example ~ is at the end of the substring, and it is also at the start of a delimiter.
Therefore you can use ~ as part of the delimiter itself and use ~9N, ~1T etc in a regular expression to split up the string. This solves the problem with single char delimiters as D and S now become ~D and ~S.
Second issue is solved by matching on } in the regular expression and eliminating it from the output by not capturing it as part of the substring following ~S.
Sample code:
// your input
var str = ']d1[)½}06~9N110375286414~1T12345ABCD~D150600~S12345ABCDEF98765} ';
// regex to parse delimiters
var pattern = /(.*)~9N(.*)~1T(.*)~D(.*)~S(.*)\}/;
// delimiter descriptions
var dataNames = {
'9N': 'PPN',
'1T': 'batchNumber',
'D': 'expireDate',
'S': 'serialNumber'
};
// test input
console.log(parseGS1(str));
// parse function
function parseGS1(str) {
// call regex
var match = pattern.exec(str); // try console.log(match);
// output object
var data = {};
// match items 2-5 should be substrings
data[dataNames['9N']] = match[2];
data[dataNames['1T']] = match[3];
data[dataNames['D']] = match[4];
data[dataNames['S']] = match[5];
return data;
}
If your string always has the format you show in the question, you could split the string at the ~ symbol and then only check the first 2 characters of the substrings.
var string = "]d1[)½}06~9N110375286414~1T12345ABCD~D150600~S12345ABCDEF98765} "
var substrings = string.split('~');
substrings.shift(); //get rid of irrelevant first array element
substrings[substrings.length-1] = substrings[substrings.length-1].replace("} ", "");
The replace in the above exmaple eliminates the curly brace at the end. But I'm not entirely sure if that's the most elegant way. It is for sure not the most flexible, so if you face anything other than curly brace + space at the end, it would not be removed of course.
After extracting these substrings and getting rid of the very first array element, you can then concentrate on only checking the first characters in your string.

Remove all occurrences except last?

I want to remove all occurrences of substring = . in a string except the last one.
E.G:
1.2.3.4
should become:
123.4
You can use regex with positive look ahead,
"1.2.3.4".replace(/[.](?=.*[.])/g, "");
2-liner:
function removeAllButLast(string, token) {
/* Requires STRING not contain TOKEN */
var parts = string.split(token);
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Alternative version without the requirement on the string argument:
function removeAllButLast(string, token) {
var parts = string.split(token);
if (parts[1]===undefined)
return string;
else
return parts.slice(0,-1).join('') + token + parts.slice(-1)
}
Demo:
> removeAllButLast('a.b.c.d', '.')
"abc.d"
The following one-liner is a regular expression that takes advantage of the fact that the * character is greedy, and that replace will leave the string alone if no match is found. It works by matching [longest string including dots][dot] and leaving [rest of string], and if a match is found it strips all '.'s from it:
'a.b.c.d'.replace(/(.*)\./, x => x.replace(/\./g,'')+'.')
(If your string contains newlines, you will have to use [.\n] rather than naked .s)
You can do something like this:
var str = '1.2.3.4';
var last = str.lastIndexOf('.');
var butLast = str.substring(0, last).replace(/\./g, '');
var res = butLast + str.substring(last);
Live example:
http://jsfiddle.net/qwjaW/
You could take a positive lookahead (for keeping the last dot, if any) and replace the first coming dots.
var string = '1.2.3.4';
console.log(string.replace(/\.(?=.*\.)/g, ''));
A replaceAllButLast function is more useful than a removeAllButLast function. When you want to remove just replace with an empty string:
function replaceAllButLast(str, pOld, pNew) {
var parts = str.split(pOld)
if (parts.length === 1) return str
return parts.slice(0, -1).join(pNew) + pOld + parts.slice(-1)
}
var test = 'hello there hello there hello there'
test = replaceAllButLast(test, ' there', '')
console.log(test) // hello hello hello there
Found a much better way of doing this. Here is replaceAllButLast and appendAllButLast as they should be done. The latter does a replace whilst preserving the original match. To remove, just replace with an empty string.
var str = "hello there hello there hello there"
function replaceAllButLast(str, regex, replace) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : replace
})
}
function appendAllButLast(str, regex, append) {
var reg = new RegExp(regex, 'g')
return str.replace(reg, function(match, offset, str) {
var follow = str.slice(offset);
var isLast = follow.match(reg).length == 1;
return (isLast) ? match : match + append
})
}
var replaced = replaceAllButLast(str, / there/, ' world')
console.log(replaced)
var appended = appendAllButLast(str, / there/, ' fred')
console.log(appended)
Thanks to #leaf for these masterpieces which he gave here.
You could reverse the string, remove all occurrences of substring except the first, and reverse it again to get what you want.
function formatString() {
var arr = ('1.2.3.4').split('.');
var arrLen = arr.length-1;
var outputString = '.' + arr[arrLen];
for (var i=arr.length-2; i >= 0; i--) {
outputString = arr[i]+outputString;
}
alert(outputString);
}
See it in action here: http://jsbin.com/izebay
var s='1.2.3.4';
s=s.split('.');
s.splice(s.length-1,0,'.');
s.join('');
123.4

Remove/ truncate leading zeros by javascript/jquery

Suggest solution for removing or truncating leading zeros from number(any string) by javascript,jquery.
You can use a regular expression that matches zeroes at the beginning of the string:
s = s.replace(/^0+/, '');
I would use the Number() function:
var str = "00001";
str = Number(str).toString();
>> "1"
Or I would multiply my string by 1
var str = "00000000002346301625363";
str = (str * 1).toString();
>> "2346301625363"
Maybe a little late, but I want to add my 2 cents.
if your string ALWAYS represents a number, with possible leading zeros, you can simply cast the string to a number by using the '+' operator.
e.g.
x= "00005";
alert(typeof x); //"string"
alert(x);// "00005"
x = +x ; //or x= +"00005"; //do NOT confuse with x+=x, which will only concatenate the value
alert(typeof x); //number , voila!
alert(x); // 5 (as number)
if your string doesn't represent a number and you only need to remove the 0's use the other solutions, but if you only need them as number, this is the shortest way.
and FYI you can do the opposite, force numbers to act as strings if you concatenate an empty string to them, like:
x = 5;
alert(typeof x); //number
x = x+"";
alert(typeof x); //string
hope it helps somebody
Since you said "any string", I'm assuming this is a string you want to handle, too.
"00012 34 0000432 0035"
So, regex is the way to go:
var trimmed = s.replace(/\b0+/g, "");
And this will prevent loss of a "000000" value.
var trimmed = s.replace(/\b(0(?!\b))+/g, "")
You can see a working example here
parseInt(value) or parseFloat(value)
This will work nicely.
I got this solution for truncating leading zeros(number or any string) in javascript:
<script language="JavaScript" type="text/javascript">
<!--
function trimNumber(s) {
while (s.substr(0,1) == '0' && s.length>1) { s = s.substr(1,9999); }
return s;
}
var s1 = '00123';
var s2 = '000assa';
var s3 = 'assa34300';
var s4 = 'ssa';
var s5 = '121212000';
alert(s1 + '=' + trimNumber(s1));
alert(s2 + '=' + trimNumber(s2));
alert(s3 + '=' + trimNumber(s3));
alert(s4 + '=' + trimNumber(s4));
alert(s5 + '=' + trimNumber(s5));
// end hiding contents -->
</script>
Simply try to multiply by one as following:
"00123" * 1; // Get as number
"00123" * 1 + ""; // Get as string
1. The most explicit is to use parseInt():
parseInt(number, 10)
2. Another way is to use the + unary operator:
+number
3. You can also go the regular expression route, like this:
number.replace(/^0+/, '')
Try this,
function ltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}
var str =ltrim("01545878","0");
More here
You should use the "radix" parameter of the "parseInt" function :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FparseInt
parseInt('015', 10) => 15
if you don't use it, some javascript engine might use it as an octal
parseInt('015') => 0
If number is int use
"" + parseInt(str)
If the number is float use
"" + parseFloat(str)
const number = '0000007457841';
console.log(+number) //7457841;
OR number.replace(/^0+/, '')
Regex solution from Guffa, but leaving at least one character
"123".replace(/^0*(.+)/, '$1'); // 123
"012".replace(/^0*(.+)/, '$1'); // 12
"000".replace(/^0*(.+)/, '$1'); // 0
I wanted to remove all leading zeros for every sequence of digits in a string and to return 0 if the digit value equals to zero.
And I ended up doing so:
str = str.replace(/(0{1,}\d+)/, "removeLeadingZeros('$1')")
function removeLeadingZeros(string) {
if (string.length == 1) return string
if (string == 0) return 0
string = string.replace(/^0{1,}/, '');
return string
}
One another way without regex:
function trimLeadingZerosSubstr(str) {
var xLastChr = str.length - 1, xChrIdx = 0;
while (str[xChrIdx] === "0" && xChrIdx < xLastChr) {
xChrIdx++;
}
return xChrIdx > 0 ? str.substr(xChrIdx) : str;
}
With short string it will be more faster than regex (jsperf)
const input = '0093';
const match = input.match(/^(0+)(\d+)$/);
const result = match && match[2] || input;
Use "Math.abs"
eg: Math.abs(003) = 3;
console.log(Math.abs(003))

Categories

Resources