Convert number from input with/without separators to whole number - javascript

I am trying to allow only [0-9], ., and , from being input, as I only want the user to be able to input numbers with and without separators. These are the tests I want to allow:
1000 == 1.000,00
1000 == 1,000.00
1000 == 1.000
1000 == 1,000
1000 == 1000
How users type these is completely up to them and what they usually do. I want to check if what the user inputs is equal to 1000.
https://jsfiddle.net/m2pq06b1/
What is the best way to do this? I need all cases above to be true.

From the comments:
It's common that if you type three numbers after a separator, it means
thousand. It's quite common. When you only type two, it generally
means cents or hundredths of a whole (basically 1-99).
Based on that, I propose the following solution:
Replace all separators (, and .) followed by exactly two digits and the end of the string with a decimal point.
Remove all separators not followed by exactly two digits and the end of the string.
Parse the sanitized value to a number using parseFloat().
var values = ["1.000,00", "1,000.00", "1.000", "1,000","1000"];
values.forEach(value => {
let sanitized = value.replace(/[.,](?=\d{2}$)/g, '.').replace(/[.,](?!\d{2}$)/g, '');
let number = parseFloat(sanitized);
console.log(number == 1000);
});

Related

Splitting payload after fixed number of decimals

I need to split a payload in Node-RED whenever it is longer than a certain number of characters, and after a certain number of decimals.
I am working on a project where a sensor is providing feedback to Node-RED, but it sometimes puts two outputs together, and I can't seem to find a way to split the resulting data into two parts at a position which is not at the decimal point, but a number of digits AFTER the decimal point.
At the moment, I am scrapping the wrong outputs using
if (msg.payload.length < 11){return msg;}
so that only single output results are processed further, while anything else is discarded.
Output can be like 123.4567123.4687 instead of 123.4567and 123.4687.
Note that the problem only occurs sometimes (something like every 100th measurement).
Note that the number of digits BEFORE the decimal point is not necessarily the same every time, so it is not just a matter of splitting after a certain number of digits from the first.
If the number of digits after the decimal point is constant you could use a regular expression to extract the needed values, for example:
var input = "123.4567123.4678";
var results = input.match(/\d+\.\d{4}/g);
results is an array that contains the two values as strings: [ '123.4567', '123.4678' ]
The Regex globally matches one or more digits (\d+) followed by a point (\.) followed by four digits (\d{4})

Regex - checking range of numbers with constraints

In javascript I need to parse a user input. The input is of the format: number - number. This can be repeated and separated by commas.
The following are some examples:
1-10
4-10,13-17
6-10,3-8,4-12
Here is the regex I wrote for this
(\d+[-]\d+[,]?)
However, there are 2 constraints.
The first number must be less than the second number ( 4-5 is valid but 5-4 is not)
Every number must be between 1 and N (inclusive). I will specify N.
Is there a way I can enforce these constraints with regex?
While you can certainly match the format with regexes, you can't do the kind of verification you want with them. What I would recommend is something like this (in JS):
function verifyList(list) {
var matches = list.match(/\d+-\d+/g);
for (match in matches) {
var numbers = match.match(/(\d+)-(\d+)/);
if (numbers[1] >= numbers[2]) return false;
}
return true;
}

RegEx to filter out all but one decimal point [duplicate]

i need a regular expression for decimal/float numbers like 12 12.2 1236.32 123.333 and +12.00 or -12.00 or ...123.123... for using in javascript and jQuery.
Thank you.
Optionally match a + or - at the beginning, followed by one or more decimal digits, optional followed by a decimal point and one or more decimal digits util the end of the string:
/^[+-]?\d+(\.\d+)?$/
RegexPal
The right expression should be as followed:
[+-]?([0-9]*[.])?[0-9]+
this apply for:
+1
+1.
+.1
+0.1
1
1.
.1
0.1
Here is Python example:
import re
#print if found
print(bool(re.search(r'[+-]?([0-9]*[.])?[0-9]+', '1.0')))
#print result
print(re.search(r'[+-]?([0-9]*[.])?[0-9]+', '1.0').group(0))
Output:
True
1.0
If you are using mac, you can test on command line:
python -c "import re; print(bool(re.search(r'[+-]?([0-9]*[.])?[0-9]+', '1.0')))"
python -c "import re; print(re.search(r'[+-]?([0-9]*[.])?[0-9]+', '1.0').group(0))"
You can check for text validation and also only one decimal point validation using isNaN
var val = $('#textbox').val();
var floatValues = /[+-]?([0-9]*[.])?[0-9]+/;
if (val.match(floatValues) && !isNaN(val)) {
// your function
}
This is an old post but it was the top search result for "regular expression for floating point" or something like that and doesn't quite answer _my_ question. Since I worked it out I will share my result so the next person who comes across this thread doesn't have to work it out for themselves.
All of the answers thus far accept a leading 0 on numbers with two (or more) digits on the left of the decimal point (e.g. 0123 instead of just 123) This isn't really valid and in some contexts is used to indicate the number is in octal (base-8) rather than the regular decimal (base-10) format.
Also these expressions accept a decimal with no leading zero (.14 instead of 0.14) or without a trailing fractional part (3. instead of 3.0). That is valid in some programing contexts (including JavaScript) but I want to disallow them (because for my purposes those are more likely to be an error than intentional).
Ignoring "scientific notation" like 1.234E7, here is an expression that meets my criteria:
/^((-)?(0|([1-9][0-9]*))(\.[0-9]+)?)$/
or if you really want to accept a leading +, then:
/^((\+|-)?(0|([1-9][0-9]*))(\.[0-9]+)?)$/
I believe that regular expression will perform a strict test for the typical integer or decimal-style floating point number.
When matched:
$1 contains the full number that matched
$2 contains the (possibly empty) leading sign (+/-)
$3 contains the value to the left of the decimal point
$5 contains the value to the right of the decimal point, including the leading .
By "strict" I mean that the number must be the only thing in the string you are testing.
If you want to extract just the float value out of a string that contains other content use this expression:
/((\b|\+|-)(0|([1-9][0-9]*))(\.[0-9]+)?)\b/
Which will find -3.14 in "negative pi is approximately -3.14." or in "(-3.14)" etc.
The numbered groups have the same meaning as above (except that $2 is now an empty string ("") when there is no leading sign, rather than null).
But be aware that it will also try to extract whatever numbers it can find. E.g., it will extract 127.0 from 127.0.0.1.
If you want something more sophisticated than that then I think you might want to look at lexical analysis instead of regular expressions. I'm guessing one could create a look-ahead-based expression that would recognize that "Pi is 3.14." contains a floating point number but Home is 127.0.0.1. does not, but it would be complex at best. If your pattern depends on the characters that come after it in non-trivial ways you're starting to venture outside of regular expressions' sweet-spot.
Paulpro and lbsweek answers led me to this:
re=/^[+-]?(?:\d*\.)?\d+$/;
>> /^[+-]?(?:\d*\.)?\d+$/
re.exec("1")
>> Array [ "1" ]
re.exec("1.5")
>> Array [ "1.5" ]
re.exec("-1")
>> Array [ "-1" ]
re.exec("-1.5")
>> Array [ "-1.5" ]
re.exec(".5")
>> Array [ ".5" ]
re.exec("")
>> null
re.exec("qsdq")
>> null
For anyone new:
I made a RegExp for the E scientific notation (without spaces).
const floatR = /^([+-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?)$/;
let str = "-2.3E23";
let m = floatR.exec(str);
parseFloat(m[1]); //=> -2.3e+23
If you prefer to use Unicode numbers, you could replace all [0-9] by \d in the RegExp.
And possibly add the Unicode flag u at the end of the RegExp.
For a better understanding of the pattern see https://regexper.com/.
And for making RegExp, I can suggest https://regex101.com/.
EDIT: found another site for viewing RegExp in color: https://jex.im/regulex/.
EDIT 2: although op asks for RegExp specifically you can check a string in JS directly:
const isNum = (num)=>!Number.isNaN(Number(num));
isNum("123.12345678E+3");//=> true
isNum("80F");//=> false
converting the string to a number (or NaN) with Number()
then checking if it is NOT NaN with !Number.isNaN()
If you want it to work with e, use this expression:
[+-]?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?
Here is a JavaScript example:
var re = /^[+-]?[0-9]+([.][0-9]+)?([eE][+-]?[0-9]+)?$/;
console.log(re.test('1'));
console.log(re.test('1.5'));
console.log(re.test('-1'));
console.log(re.test('-1.5'));
console.log(re.test('1E-100'));
console.log(re.test('1E+100'));
console.log(re.test('.5'));
console.log(re.test('foo'));
Here is my js method , handling 0s at the head of string
1- ^0[0-9]+\.?[0-9]*$ : will find numbers starting with 0 and followed by numbers bigger than zero before the decimal seperator , mainly ".". I put this to distinguish strings containing numbers , for example, "0.111" from "01.111".
2- ([1-9]{1}[0-9]\.?[0-9]) : if there is string starting with 0 then the part which is bigger than 0 will be taken into account. parentheses are used here because I wanted to capture only parts conforming to regex.
3- ([0-9]\.?[0-9]): to capture only the decimal part of the string.
In Javascript , st.match(regex), will return array in which first element contains conformed part. I used this method in the input element's onChange event , by this if the user enters something that violates the regex than violating part is not shown in element's value at all but if there is a part that conforms to regex , then it stays in the element's value.
const floatRegexCheck = (st) => {
const regx1 = new RegExp("^0[0-9]+\\.?[0-9]*$"); // for finding numbers starting with 0
let regx2 = new RegExp("([1-9]{1}[0-9]*\\.?[0-9]*)"); //if regx1 matches then this will remove 0s at the head.
if (!st.match(regx1)) {
regx2 = new RegExp("([0-9]*\\.?[0-9]*)"); //if number does not contain 0 at the head of string then standard decimal formatting takes place
}
st = st.match(regx2);
if (st?.length > 0) {
st = st[0];
}
return st;
}
Here is a more rigorous answer
^[+-]?0(?![0-9]).[0-9]*(?![.])$|^[+-]?[1-9]{1}[0-9]*.[0-9]*$|^[+-]?.[0-9]+$
The following values will match (+- sign are also work)
.11234
0.1143424
11.21
1.
The following values will not match
00.1
1.0.00
12.2350.0.0.0.0.
.
....
How it works
The (?! regex) means NOT operation
let's break down the regex by | operator which is same as logical OR operator
^[+-]?0(?![0-9]).[0-9]*(?![.])$
This regex is to check the value starts from 0
First Check + and - sign with 0 or 1 time ^[+-]
Then check if it has leading zero 0
If it has,then the value next to it must not be zero because we don't want to see 00.123 (?![0-9])
Then check the dot exactly one time and check the fraction part with unlimited times of digits .[0-9]*
Last, if it has a dot follow by fraction part, we discard it.(?![.])$
Now see the second part
^[+-]?[1-9]{1}[0-9]*.[0-9]*$
^[+-]? same as above
If it starts from non zero, match the first digit exactly one time and unlimited time follow by it [1-9]{1}[0-9]* e.g. 12.3 , 1.2, 105.6
Match the dot one time and unlimited digit follow it .[0-9]*$
Now see the third part
^[+-]?.{1}[0-9]+$
This will check the value starts from . e.g. .12, .34565
^[+-]? same as above
Match dot one time and one or more digits follow by it .[0-9]+$

Regex for validating currency number format

I've got following formats, that are acceptable
1200000,00
1200000.00
1,200,000.00
1 200 000.00
1 200 000,00
1 200 000,0000
-1 200 000.00
At the moment I was able to verify only ^-?\\d+$, ^-?\\d+[\\,\\.]\\d{2}$, ^-?\\d+[\\,\\.]\\d{2,}$. Two last format are separate, so that I would know is rounding needed or not. All three format use gm flags to check string from start ^ to end $.
Those regular expressions cover only first two elements in list. Other elements, that use commas and spaces for thousand separation are not verified yet and I'm not sure how to achieve that.
Also there is a "beautifier" expression (\\d)(?=(\\d{3})+(?!\\d)), that will take this 1200000,00 and turn it into 1 200 000,00 with such usage '1200000,00'.replace(('(\\d)(?=(\\d{3})+(?!\\d))', 'g'), '$1 ').
So question states, what would be a correct regular expression to validate such format 1 200 000.00 or 1,200,000.00? Since I assume difference with \s\, could be easily done in same expression.
Thank you.
For validating the last two numbers, you can use the following:
^-?\d{1,3}(?:[\s,]\d{3})*(?:\.\d+)?$
1 2 3 4 5
Optional minus sign
1..3 digits
Zero or more fragments that consist of
comma or space
3 digits
optional fraction part consisting of a dot followed by 1 or more digits.
This doesn't directly solve the problem due to me misreading. But it might still be useful to someone so I'll let it stay.
Stop trying to solve every problem with regex. Regex is great when you have one or two very well defined strings. Not a million formats.
This can be solved with minimal regex. Magic is in the bold part.
var numbers = [
"1200000,00",
"1200000.00",
"1,200,000.00",
"1 200 000.00",
"1 200 000,00",
"1 200 000,0000",
"-1 200 000.00"
];
var parseWeirdNumber = function(numberString) {
//Split numbers to parts. , . and space are all valid delimiters.
var numberParts = numberString.split(/[.,\s]/);
//Remove the last part. **This means that all input must have fraction!!**
var fraction = numberParts.pop();
//Rejoin back without delimiters, and reapply the fraction.
//parseFloat to convert to a number
var number = parseFloat(numberParts.join('') + "." + fraction);
return number;
}
numbers = numbers.map(parseWeirdNumber);
console.log(numbers);

Only allow a single dot point in input field

I have an input field which has:
$(".double").alphanumeric({allow:" ",ichars:"`~!##$%^&*=_+[]\\{}|;\":,/<>?'-()\/abcdefghijklmnopqrstuvwxyzABCDFEGHIJKLMNOPQRSTUVWXYZ"});
validation applied to it.
I need to further restrict entry so that only a single decimal place can be added e.g. 100.00 or 255.95
The input is used for currency so I need to only allow 1 decimal point. At the moment its allow 100.00.00 which messes up the system!
Thanks
Here is a regex that will only allow positive/negative decimal numbers
^[-]?((\d+)|(\d+\.\d+)|(\.\d+))$
With jquery you can test the value
if (/^[-]?((\d+)|(\d+\.\d+)|(\.\d+))$/.test($(".double").val())) { .... }
A simple function to allow an optional leading + or - and only digits with an optional decimal place is:
function validate(value) {
var re = /^[-+]?\d+(\.\d+)?$/;
return re.test(value);
}
However since you want money, you might want:
var re = /^[-+]?\d+(\.\d\d)?$/;
which will require two digits after the decimal place, if there is one.

Categories

Resources