I have many strings like this:
0001, 0002, ..., 0010, 0011, ..., 0100, 0101,...
I would like these to become like this:
1, 2, ..., 10, 11, ..., 100, 101, ...
So I would like to remove all the 0 chars before a different char is present.
I tried with
.replace(/0/g, '')
But of course then it also removes the 0 chars after. Therefore for example 0010 becomes 1 instead of 10. Can you please help me?
You can do
.replace(/\d+/g, function(v){ return +v })
This is the shortes Solution
"0001".replace(/^0+/,""); // => 1
...
// Tested on Win7 Chrome 44+
^ ... starting of the String
0+ ... At least one 0
P.s.: test Regex on pages likes: https://regex101.com/ or https://www.debuggex.com
Update 1:
For one long String
"0001, 0002, 0010, 0011, 0100, 0101".replace(/(^|\s)0+/g,"") // => 1, 2, 10, 11, 100, 101
// Tested on Win7 Chrome 44+
Examples:
// short Strings
var values = ['0001', '0002','0010', '0011','0100','0101'];
for(var idx in values){
document.write(values[idx] + " -> "+values[idx].replace(/^0+/,"") + "<br/>");
}
// one long String
document.write("0001, 0002, 0010, 0011, 0100, 0101".replace(/(^|\s)0+/g,""));
Previously answered here.
.replace(/^0+(?!$)/, '')
Functionally the same as winner_joiner's answer, with the exception that this particular regex won't return a completely empty string should the input consist entirely of zeroes.
Use regex as /(^|,\s*)0+/g it will select 0's at beginning or followed by , and space
document.write('0001, 0002, ..., 0010, 0011, ..., 0100, 0101,...'.replace(/(^|,\s*)0+/g,'$1'))
Explanation :
(^|,\s*)0+
Debuggex Demo
var text='00101';
var result=parseInt(text);
Related
For example, I have user input any string: "1st", "2nd", "third", "fourth", "fifth", "9999th", etc. These are just examples, the user can input any string.
I want to map this to integer cardinality:
"1st" -> 0
"2nd" -> 1
"third" -> 2
"fourth" -> 3
"fifth" -> 4
"9999th" -> 9998
So I need some kind of function where:
function mapCardinality(input: string): number{
let numberResult:number = ??
return numberREesult;
}
and I can call it like this:
console.log(
mapCardinality("1st"), // print 0
mapCardinality("2nd"), // print 1
mapCardinality("third"), // print 2
mapCardinality("fourth"), // print 3
mapCardinality("fifth"), // print 4
mapCardinality("9999th") // print 9998
);
Just look it up in an array or parse it as number:
const mapCardinality = c => {
const pos = ["1st", "2nd", "third", "fourth", "fifth"].indexOf(c);
return pos === -1 ? parseInt(c, 10) - 1 : pos;
};
I'd first ask what are the suffixes for all of the inputs?
'nd', 'rd', 'st', 'th' (most numbers)
If they enter an integer with the above prefixes then you could write the following function:
const getInteger = input => input.slice(0, -2);
const num = getInteger('999th');
console.log(num); // prints "999"
If they enter the elongated variant, it becomes much more complex, especially when it comes to typos, lack of spaces, etc. One way could be to map single digit words ('one', 'two', etc), tens ('ten', 'twenty', etc'), hundreds, thousands, and so on instead of every number imaginable. I would then parse and find matching words to give a result. That being said it is still limiting. I would strongly suggest limiting user input formats. Why can't the user input an integer?
const cardinalDictionary = {
'zero': 0,
'one': 1,
...,
'twenty',
...,
'hundred': 100,
'thousand': 1000,
};
I'm new to RegExp and to JS in general (Coming from Python), so this might be an easy question:
I'm trying to code an algebraic calculator in Javascript that receives an algebraic equation as a string, e.g.,
string = 'x^2 + 30x -12 = 4x^2 - 12x + 30';
The algorithm is already able to break the string in a single list, with all values on the right side multiplied by -1 so I can equate it all to 0, however, one of the steps to solve the equation involves creating a hashtable/dictionary, having the variable as key.
The string above results in a list eq:
eq = ['x^2', '+30x', '-12', '-4x^2', '+12x', '-30'];
I'm currently planning on iterating through this list, and using RegExp to identify both variables and the respective multiplier, so I can create a hashTable/Dictionary that will allow me to simplify the equation, such as this one:
hashTable = {
'x^2': [1, -4],
'x': [30, 12],
' ': [-12]
}
I plan on using some kind of for loop to iter through the array, and applying a match on each string to get the values I need, but I'm quite frankly, stumped.
I have already used RegExp to separate the string into the individual parts of the equation and to remove eventual spaces, but I can't imagine a way to separate -4 from x^2 in '-4x^2'.
You can try this
(-?\d+)x\^\d+.
When you execute match function :
var res = "-4x^2".match(/(-?\d+)x\^\d+/)
You will get res as an array : [ "-4x^2", "-4" ]
You have your '-4' in res[1].
By adding another group on the second \d+ (numeric char), you can retrieve the x power.
var res = "-4x^2".match(/(-?\d+)x\^(\d+)/) //res = [ "-4x^2", "-4", "2" ]
Hope it helps
If you know that the LHS of the hashtable is going to be at the end of the string. Lets say '4x', x is at the end or '-4x^2' where x^2 is at end, then we can get the number of the expression:
var exp = '-4x^2'
exp.split('x^2')[0] // will return -4
I hope this is what you were looking for.
function splitTerm(term) {
var regex = /([+-]?)([0-9]*)?([a-z](\^[0-9]+)?)?/
var match = regex.exec(term);
return {
constant: parseInt((match[1] || '') + (match[2] || 1)),
variable: match[3]
}
}
splitTerm('x^2'); // => {constant: 1, variable: "x^2"}
splitTerm('+30x'); // => {constant: 30, variable: "x"}
splitTerm('-12'); // => {constant: -12, variable: undefined}
Additionally, these tool may help you analyze and understand regular expressions:
https://regexper.com/
https://regex101.com/
http://rick.measham.id.au/paste/explain.pl
I am trying to use the exec method on the JavaScript Regex object and can get into an infinite loop where exec does not return a null depending on the expression.
Here is a test function I wrote to illustrate the problem. I ran it in Chrome 32. I am defining the Regex and match variables outside the loop. The max/Reached Max test is there to break out of the infinite loop.
function textExec(reg, text, max) {
max = max || 10
var match = null;
while (match = reg.exec(text)) {
console.log(match);
console.log(match.length + " " + match.index + "," + reg.lastIndex);
if (--max < 0 || match.index == reg.lastIndex) {
console.log('Reached Max');
break;
}
}
}
Here is a simple test that runs as expected.
textExec(/(o[a-z])/g, "body=//soap:Body");
["od", "od", index: 1, input: "body=//soap:Body"]
2 1,3
["oa", "oa", index: 8, input: "body=//soap:Body"]
2 8,10
["od", "od", index: 13, input: "body=//soap:Body"]
2 13,15
Here is the regular expression I am trying to use. It extracts an optional variable name and a required XPath expression. This will go into an infinite loop that is only stopped by the test I added. It appears to get to the end of the input text and hang.
textExec(/(([a-zA-Z0-9_-]*)=)?(.*)/g, "body=//soap:Body");
["body=//soap:Body", "body=", "body", "//soap:Body", index: 0, input: "body=//soap:Body"]
4 0,16
["", undefined, undefined, "", index: 16, input: "body=//soap:Body"]
4 16,16
Reached Max
Here is the same test simplified. It still sends it into an infinite loop.
textExec(/.*/g, "body=//soap:Body");
["body=//soap:Body", index: 0, input: "body=//soap:Body"]
1 0,16
["", index: 16, input: "body=//soap:Body"]
1 16,16
Reached Max
If the text includes a new-line, \n, it would hang at the character before it.
textExec(/.*/g, "//soap:Envelope\n//soap:Body");
["//soap:Envelope", index: 0, input: "//soap:Envelope?//soap:Body"]
1 0,15
["", index: 15, input: "//soap:Envelope\n//soap:Body"]
1 15,15
Reached Max
I would appreciate any help.
Wes.
The pattern .* matches the zero characters in the source string that come after the first match. It will keep on matching those zero characters forever. You could simplify a demonstration of that by matching against the empty string in the first place.
What you could do is quit when the match position stops changing.
I am currently learning regex but need this quite urgently.
I have a set of values (10, 19.5, 13.99, 9.09). These formats are fine except for the second value.
My problem is how to rewrite so that 19.5 becomes 19.50 without affecting the other entries i.e (10, 19.50, 13.99, 9.09)
Many thanks guys.
If these are numbers, use toFixed()
If these are strings, you can use
num="19.5"
num.replace(/^(\d+\.\d)$/,"$10");
Search for:
(\.\d)(\D|$)
That's dot followed by one number, then something that isn't a number (or end of string).
Replace with:
$10$2
That's the first capture group, then '0', then the second capture group.
var s = '10, 19.5, 13.99, 9.9';
s = s.replace(/(\.\d)(\D|$)/g, '$10$2');
// s == '10, 19.50, 13.99, 9.90'
For example, iterating each value:
var value = '19.5';
value = value.replace(/^\d+[\.,]\d{1}$/, '$&0');
If you wanted to use RegEx you could do something like:
"10, 19.5, 13.99, 9.09".replace(/^\d+\.\d{1}$/g, function (full) {
return full + "0";
});
This would return "10, 19.50, 13.99, 9.09".
try this
var array = [10, 19.5, 13.99, 9.09];
for(var i=0; i< array.length;i++){
if(/[0-9].[0-9]{1}$/.test(array[i])) array[i] = array[i]+'0';
}
alert(array);
OUTPUT :
10, 19.50, 13.99, 9.09
fiddle : http://jsfiddle.net/M9hZx/
EDITED ANSWER:
<script type="text/javascript">
var num = 19.9;
if(String(num).indexOf('.')>-1)
{
num = num.toFixed(2);
}
alert(num);
</script>
The straight answer is to use ".toFixed(2)", but we verify if it is a decimal so that we don't have results like "10.00"
For further formatting options you have the jquery plugin numberformatter:
http://archive.plugins.jquery.com/project/numberformatter
Here is the project webpage:
http://code.google.com/p/jquery-numberformatter/
The direct link for this library:
http://jquery-numberformatter.googlecode.com/files/jquery.numberformatter-1.2.2.jsmin.js
I want to convert the following string '14 2' into an array of two integers.
How can I do it ?
A quick one for modern browsers:
'14 2'.split(' ').map(Number);
// [14, 2]`
You can .split() to get an array of strings, then loop through to convert them to numbers, like this:
var myArray = "14 2".split(" ");
for(var i=0; i<myArray.length; i++) { myArray[i] = +myArray[i]; }
//use myArray, it's an array of numbers
The +myArray[i] is just a quick way to do the number conversion, if you're sure they're integers you can just do:
for(var i=0; i<myArray.length; i++) { myArray[i] = parseInt(myArray[i], 10); }
SO...older thread, I know, but...
EDIT
#RoccoMusolino had a nice catch; here's an alternative:
TL;DR:
const intArray = [...("5 6 7 69 foo 0".split(' ').filter(i => /\d/g.test(i)))]
WRONG: "5 6 note this foo".split(" ").map(Number).filter(Boolean); // [5, 6]
There is a subtle flaw in the more elegant solutions listed here, specifically #amillara and #Marcus' otherwise beautiful answers.
The problem occurs when an element of the string array isn't integer-like, perhaps in a case without validation on an input. For a contrived example...
The problem:
var effedIntArray = "5 6 7 69 foo".split(' ').map(Number); // [5, 6, 7, 69, NaN]
Since you obviously want a PURE int array, that's a problem. Honestly, I didn't catch this until I copy-pasted SO code into my script... :/
The (slightly-less-baller) fix:
var intArray = "5 6 7 69 foo".split(" ").map(Number).filter(Boolean); // [5, 6, 7, 69]
So, now even when you have crap int string, your output is a pure integer array. The others are really sexy in most cases, but I did want to offer my mostly rambly w'actually. It is still a one-liner though, to my credit...
Hope it saves someone time!
var result = "14 2".split(" ").map(function(x){return parseInt(x)});
An alternative to Tushar Gupta answer would be :
'14 2'.split(' ').map(x=>+x);
// [14, 2]`
In code golf you save 1 character.
Here the "+" is "unary plus" operator, works like parseInt.
First split the string on spaces:
var result = '14 2'.split(' ');
Then convert the result array of strings into integers:
for (var i in result) {
result[i] = parseInt(result[i], 10);
}
The point against parseInt-approach:
There's no need to use lambdas and/or give radix parameter to parseInt, just use parseFloat or Number instead.
Reasons:
It's working:
var src = "1,2,5,4,3";
var ids = src.split(',').map(parseFloat); // [1, 2, 5, 4, 3]
var obj = {1: ..., 3: ..., 4: ..., 7: ...};
var keys= Object.keys(obj); // ["1", "3", "4", "7"]
var ids = keys.map(parseFloat); // [1, 3, 4, 7]
var arr = ["1", 5, "7", 11];
var ints= arr.map(parseFloat); // [1, 5, 7, 11]
ints[1] === "5" // false
ints[1] === 5 // true
ints[2] === "7" // false
ints[2] === 7 // true
It's shorter.
It's a tiny bit quickier and takes advantage of cache, when parseInt-approach - doesn't:
// execution time measure function
// keep it simple, yeah?
> var f = (function (arr, c, n, m) {
var i,t,m,s=n();
for(i=0;i++<c;)t=arr.map(m);
return n()-s
}).bind(null, "2,4,6,8,0,9,7,5,3,1".split(','), 1000000, Date.now);
> f(Number) // first launch, just warming-up cache
> 3971 // nice =)
> f(Number)
> 3964 // still the same
> f(function(e){return+e})
> 5132 // yup, just little bit slower
> f(function(e){return+e})
> 5112 // second run... and ok.
> f(parseFloat)
> 3727 // little bit quicker than .map(Number)
> f(parseFloat)
> 3737 // all ok
> f(function(e){return parseInt(e,10)})
> 21852 // awww, how adorable...
> f(function(e){return parseInt(e)})
> 22928 // maybe, without '10'?.. nope.
> f(function(e){return parseInt(e)})
> 22769 // second run... and nothing changes.
> f(Number)
> 3873 // and again
> f(parseFloat)
> 3583 // and again
> f(function(e){return+e})
> 4967 // and again
> f(function(e){return parseInt(e,10)})
> 21649 // dammit 'parseInt'! >_<
Notice: In Firefox parseInt works about 4 times faster, but still slower than others. In total: +e < Number < parseFloat < parseInt
If the numbers can be separated by more than one space, it is safest to split the string on one or more consecutive whitespace characters (which includes tabs and regular spaces). With a regular expression, this would be \s+.
You can then map each element using the Number function to convert it. Note that parseInt will not work (i.e. arr.map(parseInt)) because map passes three arguments to the mapping function: the element, the index, and the original array. parseInt accepts the base or radix as the second parameter, so it will end up taking the index as the base, often resulting in many NaNs in the result. However, Number ignores any arguments other than the first, so it works directly.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(Number); //[1,2,3,4]
To remove elements that are not numbers, Array#filter can be used in conjunction with isNaN.
const str = '1\t\t2 3 ab 4 c';
const result = str.split(/\s+/).map(Number).filter(x => !isNaN(x)); //[1,2,3,4]
You could also use an anonymous function for the mapping callback with the unary plus operator to convert each element to a number.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(x => +x); //[1,2,3,4]
With an anonymous function for the callback, you can decide what parameters to use, so parseInt can also work.
const str = '1\t\t2 3 4';
const result = str.split(/\s+/).map(x => parseInt(x)); //[1,2,3,4]
Just for fun I thought I'd throw a forEach(f()) solution in too.
var a=[];
"14 2".split(" ").forEach(function(e){a.push(parseInt(e,10))});
// a = [14,2]
let idsArray = ids.split(',').map((x) => parseInt(x));
Better one line solution:
var answerInt = [];
var answerString = "1 2 3 4";
answerString.split(' ').forEach(function (item) {
answerInt.push(parseInt(item))
});
us the split function:
var splitresult = "14 2".split(" ");