I need to format my numbers and I am using regex /(?=(?!^)(?:\d{3})+$)/g, to replace and insert , where it is necessary. But currently I have an issue with negative {3} 000 numbers, so comma is added after minus.
What am I doing wrong?
'-200'.replace(/(?=(?!^)(?:\d{3})+$)/g, ',')
returns: -,200
correct: -200
'-2000'.replace(/(?=(?!^)(?:\d{3})+$)/g, ',')
returns: -2,000
correct: -2,000
You can use this regex:
var num = '-2000';
var repl = num.replace(/(\d)(?=(?:\d{3})+$)/m, '$1,');
or
var repl = num.replace(/(?=(?:\B\d{3})+$)/m, ',');
RegEx Demo
I suggest you to replace ^ with \b
(?=(?!\b)(?:\d{3})+$)
DEMO
(?!^) asserts that we are not at the start only, but (?!\b) asserts that we are not between a word char and a non-word character (vice-versa).
Example:
alert('-200'.replace(/(?=(?!\b)(?:\d{3})+$)/g, ','))
alert('-2000'.replace(/(?=(?!\b)(?:\d{3})+$)/g, ','))
To handle signed numbers, I'd recommend using something else than a regex
function formatInteger(num) {
var str = ('' + num).split('.')[0];
var sign = (str.charAt(0) === '-') && '-' || '';
if (sign) {
str = str.substr(1);
}
return sign + str.split('').reduceRight(function (result, char) {
if (result.length % 4 === 0) {
char += ',';
}
return char + result;
}, '').slice(0, -1);
}
If you feed this function a float, it will be truncated.
formatInteger(123456.123); // "123,456"
formatInteger(-1594504924) // "-1,594,504,924"
An other way:
var nb = '-2000000';
nb = nb.split(/\B/).reduce(function(p, c, i, a) {
return p + ((a.length-i)%3 ? c : ',' + c);
});
Related
I want to truncate a string with a limit of characters and a condition for the last character that should be a space (this way I have no truncated words)
Example :
var sentence = "The string that I want to truncate!";
sentence.methodToTruncate(14); // 14 is the limit of max characters
console.log("Truncated result : " + sentence); // Truncated result : The string
You can use truncate one-liner below:
const sentence = "The string that I want to truncate!";
const truncate = (str, len) => str.substring(0, (str + ' ').lastIndexOf(' ', len));
console.log(truncate(sentence, 14));
Here's how you can truncate by words and given limit -
String.prototype.methodToTruncate = function(n) {
var parts = this.split(" ");
var result = "";
var i = 0;
while(result.length >= n || i < parts.length) {
if (result.length + parts[i].length > n) {
break;
}
result += " " + parts[i];
i++;
}
return result;
}
var sentence = "The string that I want to truncate!";
console.log("Truncated result : " + sentence.methodToTruncate(14)); // Truncated result : The string
First you can have a max substring of your string, and then recursively remove the letters until you find spaces.
Note that this response is made without doing monkey patching and so, not extending String.prototype :
var sentence = "Hello a";
var a = methodToTruncate(sentence, 5); // 14 is the limit of max characters
console.log("Truncated result : " + a); // Truncated result : The string
function methodToTruncate(str, num) {
if(num>= str.length){ return str;}
var res = str.substring(0, num);
while (str[res.length] != " " && res.length != 0) {
console.log(res.length)
res = res.substring(0, res.length-1);
}
return res;
}
I am trying to convert both sentence case and camel case to spinal case.
I am able to change camel case to by adding a space before every capital letter, but when I apply it to sentences with capital letters after spaces, I get extra spacing.
Here is my function so far :
function spinalCase(str) {
var noCamel = str.replace(/([A-Z])/g, ' $1');
var newStr = noCamel.replace(/\s|_/g, "-");
return newStr.toLowerCase();
}
spinalCase("makeThisSpinal"); //returns make-this-spinal
spinalCase("Make This Spinal"); //returns -make--this--spinal
Get lodash, specifically, https://lodash.com/docs#kebabCase.
_.kebabCase('makeThisSpinal') // make-this-spinal
_.kebabCase('Even Sentences Work') // even-sentences-work
Instead of:
var noCamel = str.replace(/([A-Z])/g, ' $1');
Try:
var noCamel = str.replace(/(\B[A-Z])/g, ' $1');
It's because you're replacing all capital letters with a space and its lowercase letter. So in your sentence, you're getting two spaces before this and spinal.
What you can do is replace all uppercase letters with "-$1" and then just remove all spaces from the string.
function spinalCase(str) {
var noCamel = str.replace(/([a-z](?=[A-Z]))/g, '$1 ')
var newStr = noCamel.replace(/\s|_/g, "-");
return newStr.toLowerCase();
}
spinalCase("makeThisSpinal"); //returns make-this-spinal
spinalCase("Make This Spinal"); //returns -make-this-spinal
Instead of str.replace(/([A-Z])/g, ' $1') for the camel case split, you should use str.replace(/([a-z](?=[A-Z]))/g, '$1 ') which will space out each word regardless of case.
Here's my solution, perhaps you will find it good reference:
function spinalCase(str) {
var newStr = str[0];
for (var j = 1; j < str.length; j++) {
// if not a letter make a dash
if (str[j].search(/\W/) !== -1 || str[j] === "_") {
newStr += "-";
}
// if a Capital letter is found
else if (str[j] === str[j].toUpperCase()) {
// and preceded by a letter or '_'
if (str[j-1].search(/\w/) !== -1 && str[j-1] !== "_") {
// insert '-' and carry on
newStr += "-";
newStr += str[j];
}
else {
newStr += str[j];
}
}
else {
newStr += str[j];
}
}
newStr = newStr.toLowerCase();
return newStr;
}
There's usually some magical way to do something in javascript.
Take for example the string
10h49m02s
and wanting to convert it to
10 hours, 49 minutes, 2 seconds
while avoid empty hours/minutes/seconds
eg2
00h10m20s
This is what I'm doing which is probably hilarious
var arr = time.split('');
var hourMaj = arr[0];
var hourMin = arr[1];
var minMaj = arr[3];
var minMin = arr[4];
var secMaj = arr[6];
var secMin = arr[7];
var str = "";
if(hourMaj !== '0'){
str += hourMaj;
str += hourMin;
}else if (hourMin !== '0'){
str += hourMin;
}
if(hourMaj !== '0' || hourMin !== '0')
str += "hours, ";
... and on
You can actually use a regex to match your values and replace h, m and s with expanded words only if the captured texts are not zeros, like this:
var re = /\b0*(\d{1,2})h0*(\d{1,2})m0*(\d{1,2})s\b/g;
var str = '10h49m02s';
var str2 = '00h10m20s';
function func(match, h, m, s) {
var p = '';
if (h !== '0') {
p += h + " hours"
}
if (m !== '0') {
p += (p.length > 0 ? ", " : "") + m + " minutes"
}
if (s !== '0') {
p += (p.length > 0 ? ", " : "") + s + " seconds"
}
return p;
}
var res = str.replace(re, func);
document.write(res + "<br/>");
res = str2.replace(re, func);
document.write(res);
The regex - \b0*(\d{1,2})h0*(\d{1,2})m0*(\d{1,2})s\b - matches:
\b - word boundary
0* - 0 or more leading zeros
(\d{1,2}) - hours, 1 or 2 digits
h0* - h literally and 0 or more zeros
(\d{1,2}) - minutes, 1 or 2 digits
m0* - m literally and 0 or more zeros
(\d{1,2}) - seconds, 1 or 2 digits
s\b - s at the end of the "word".
Similar to stribizhev's answer, but with a much simpler regular expression. I've used reduce but a for loop is no more code and would probably be faster:
function parseTime(s) {
// Match sequences of numbers or letters
var b = s.match(/\d+|[a-z]+/gi);
var words = {h:'hour', m:'minute', s:'second'};
var result;
// If some matches found
if (b) {
// Do replacement
result = b.reduce(function(acc, p, i) {
// Only include values that aren't zero
// and skip letters - +p => NaN
if (+p) {
// Change letters to words, add plural and store in array
acc.push(+p + words[b[i+1]] + (p==1? '' : 's'));
}
// Pass the accumulator array to the next iteration
return acc;
},[])
}
// Format the result
return result.join(', ');
}
document.write(parseTime('00h00m02s') + '<br>');
document.write(parseTime('10h40m02s') + '<br>');
document.write(parseTime('10h00m51s') + '<br>');
document.write(parseTime('01h32m01s'));
I am trying to create a regex that allows only the following 0-9, plus symbol, minus symbol and brackets (). No limitations on length of each of the mentioned. So far I have this but it does not seem to work.
/^[0-9 -+]+$/
Hyphen - has to be at the end of charlist, else it means interval.
/^[0-9 ()+-]+$/
0-9 is possible to write shortly as \d
/^[\d ()+-]+$/
This should work for you:
^[\d\(\)\-+]+$
^ -> start of string
\d -> same as [0-9]
+ -> one or more repetitions
$ -> end of string
DEMO
var re = /^[\d\(\)\-+]+$/m;
var str = ['09+()1213+-','fa(-ds'];
var m;
var result = "";
for(var i = 0; i < str.length; i++) {
if ((m = re.exec(str[i])) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
result += "\""+str[i]+ "\"" + " is matched:" + (m != null) + "</br>";
}
document.getElementById("results").innerHTML = result
<div id="results"></div>
To match digits, +, -, (, and ) use:
[+()\d-]+
The trick is the position of the characters inside the character class.
if (/^[+()\d-]+$/.test(text)) {
} else {
}
var re = /^[\w\(\)\-\!\+\*\&\%\$#\#\[\]\{\}\<\>\s]+$/m;
var str = ['09+()1213+-[#test#gmail{}<>','fa(-ds'];
var m;
var result = "";
for(var i = 0; i < str.length; i++) {
if ((m = re.exec(str[i])) !== null) {
if (m.index === re.lastIndex) {
re.lastIndex++;
}
// View your result using the m-variable.
// eg m[0] etc.
}
result += "\""+str[i]+ "\"" + " is matched:" + (m != null) + "</br>";
}
document.getElementById("results").innerHTML = result
<div id="results"></div>
[\d\(\)\+\-\(\)]
That should do it.
EDIT: But since some agree the escaping is too much, here ya go:
[\d+()-]
I want to format numbers. I have seen some of the regex expression example to insert comma in number string. All of them check 3 digits in a row and then insert comma in number. But i want something like this:
122 as 122
1234 as 1,234
12345 as 12,345
1723456 as 17,23,456
7123456789.56742 as 7,12,34,56,789.56742
I am very new to regex expression. Please help me how to display the number as the above. I have tried the below method. This always checks for 3 digits and then add comma.
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
But i want comma every 2 digits except for the last 3 digits before the decimals as shown above.
The result will depend on your browsers locale. But this might be an acceptable solution:
(7123456789.56742).toLocaleString();
Outputs:
7,123,456,789.56742
Try it and see if it outputs 7,12,34,56,789.567421 in your locale.
Here's a function to convert a number to a european (1.000,00 - default) or USA (1,000.00) style:
function sep1000(somenum,usa){
var dec = String(somenum).split(/[.,]/)
,sep = usa ? ',' : '.'
,decsep = usa ? '.' : ',';
return dec[0]
.split('')
.reverse()
.reduce(function(prev,now,i){
return i%3 === 0 ? prev+sep+now : prev+now;}
)
.split('')
.reverse()
.join('') +
(dec[1] ? decsep+dec[1] :'')
;
}
Alternative:
function sep1000(somenum,usa){
var dec = String(somenum).split(/[.,]/)
,sep = usa ? ',' : '.'
,decsep = usa ? '.' : ',';
return xsep(dec[0],sep) + (dec[1] ? decsep+dec[1] :'');
function xsep(num,sep) {
var n = String(num).split('')
,i = -3;
while (n.length + i > 0) {
n.splice(i, 0, sep);
i -= 4;
}
return n.join('');
}
}
//usage for both functions
alert(sep1000(10002343123.034)); //=> 10.002.343.123,034
alert(sep1000(10002343123.034,true)); //=> 10,002,343,123.034
[edit based on comment] If you want to separate by 100, simply change i -= 4; to i -= 3;
function sep100(somenum,usa){
var dec = String(somenum).split(/[.,]/)
,sep = usa ? ',' : '.'
,decsep = usa ? '.' : ',';
return xsep(dec[0],sep) + (dec[1] ? decsep+dec[1] :'');
function xsep(num,sep) {
var n = String(num).split('')
,i = -3;
while (n.length + i > 0) {
n.splice(i, 0, sep);
i -= 3; //<== here
}
return n.join('');
}
}
use toLocaleString();
It automatically handles inserting commas and will also handle uk strings the right way
e.g.
var num=63613612837131;
alert(num.toLocaleString());
Below is the snippet of code, can be done in better way but this works :D
function formatDollar(num)
{
var p = num.toFixed(2).split(".");
var chars = p[0].split("").reverse();
var sep1000 = false;
var newstr = '';
var count = 0;
var count2=0;
for (x in chars)
{
count++;
if(count%3 == 1 && count != 1 %% !sep1000)
{
newstr = chars[x] + ',' + newstr;
sep1000=true;
}
else
{
if(!sep1000)
{
newstr = chars[x] + ',' + newstr;
}
else
{
count2++;
if(count%2 == 0 && count != 1)
{
newstr = chars[x] + ',' + newstr;
}
else
{
newstr = chars[x] + newstr;
}
}
}
}
return newstr + "." + p[1];
}