I would like to know if there is a simple approach to split units and quantities apart in a string notation, where the unit is optional.
entry examples: 10, 20kg, 14h, 5;
What would you use to split for example the 20kg into 20 and kg etc?
*edit: in my examples list I didn't include decimal values, but those are also possible. (0.1 or 1.25 euro)
var string="10kg"// string="10kg"
var number=parseInt(string);//number=10
var unit=string.substr(parseInt(string).toString().length);//kg
You could use regex to split your quantities...
.match(/(\D*)(\d+)(\D*)/)
...will split your text into an array of 4 elements, the first of which will contain the original string followed by the groups of prefix, numeric value, and the suffix.
Zero or more non-digits followed by one or more digits followed by zero or more non-digits.
Here is an example, check the console:
var input = ['20kg', '40m', '$10', '50 km', '20'],
result = [];
input.forEach(function(elem) {
result.push(elem.match(/(\D*)(\d+)(\D*)/));
});
console.table(result);
You can account for the decimal places as well by changing the middle group to:
(\d+(\.\d+)?)
Digits followed by a dot and then digits if present.
Related
I want regex which finds out continues max 12 digits long number by ignoring space, plus (+), parenthesis & dash, e.g:
Primary contact number +91 98333332343 call me on this
My number is +91-983 333 32343
2nd number +1 (983) 333 32343, call me
Another one 983-333-32343
One more +91(983)-333-32343 that's all
121 street pin code 421 728 & number is 9833636363
Currently, I have a regex, which does the job of fetching contact numbers from string:
/* This only work for the first case not for any other
and for last one it outputs "121" */
\\+?\\(?\\d*\\)? ?\\(?\\d+\\)?\\d*([\\s./-]?\\d{2,})+
So what can be done here to support all the above cases, in short ignoring special characters and length should range from 10-12.
I see that there are numbers ranging from 10 to 13 digits.
You may use
/(?:[-+() ]*\d){10,13}/g
See the regex demo.
Details:
(?:[-+() ]*\d){10,13} - match 10 to 13 sequences of:
[-+() ]* - zero or more characters that are either -, +, (, ), or a space
\d - a digit
var re = /(?:[-+() ]*\d){10,13}/gm;
var str = 'Primary contact number +91 98333332343 call me on this\nMy number is +91-983 333 32343\n2nd number +1 (983) 333 32343, call me\nAnother one 983-333-32343\nOne more +91(983)-333-32343 that\'s all\n121 street pin code 421 728 & number is 9833636363';
var res = str.match(re).map(function(s){return s.trim();});
console.log(res);
The accepted answer will match your criteria but I'd like to propose a more restrictive approach. It is quite specific to the number formats you provided :
test specifically if a string IS a number /^(\+(\d{1,2})[- ]?)?(\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4,5}$/
test whether a string contains at least one number : /(\+(\d{1,2})[- ]?)?(\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4,5}/
I made you a small fiddle where you can try out different regexes on any number of... well numbers : https://jsfiddle.net/u51xrcox/5/.
have fun.
so I'm making this regular expression to verify some text boxes on a website that I'm designing for an internship.
The problem is that I'm not so keen on regular expressions, and I'm close to having a working one that matches a number between 0-24 and no more than two decimal places.
This is what I have so far. The pattern is also matching any string; such as, "a" or "az".
var pattern = "^([0-9]{0,2}?.?[0-9]{0,2}|1[0-9].?[0-9]{0,2}|2[0-4].?[0-9]{0,2})$";
To get a number between 0 and 24 (24 excluded) with optional up to two decimal places:
^(\d|1\d|2[0-3])(\.\d{1,2})?$
The decimal part:
\. - match the decimal dot
\d{1,2} - one or two digits
()? - makes it optional
The whole part:
\d - numbers 0-9
1\d - numbers 10-19
2[0-3] - numbers 20-23
(x|y|z) - one of x, y or z
As for the "why is my version matching things like "a" and "az" part" - it's a little complex, but it basically boils down to you using dots (like .?). In regex, a dot means "any one character". To make it match a literal dot, you need to escape it with a slash just like I did.
Minor remark: If you want optional leading zero for single digit numbers, replace 1\d with [01]\d. If you want mandatory leading zero for single digit numbers, replace \d|1\d with [01]\d. If you don't want leading zeroes, leave it as it is.
Assuming you do not want 05 or 5.50
^((?:[0-9]|1[0-9]|2[0-3])(?:\.(?:[1-9]|[0-9][1-9]))?)$
You can try it here
The following is a quick attempt to match a floating point number from 0 to 24.99 with up to two non-zero digits
^(([0-9])|([01][0-9])|(2[0-4]))(\.[0-9]{1,2})?$
I think it might be easier to use math to do this though...
You can see the explanation of the entire regex as well as test it out here. I have also added a few test cases.
^(\d|[01]\d|2[0-3])(\.\d{1,2})?$
Test cases:
Valid:
22
1.29
2.99
9.99
13.24
17.38
20.01
02.15
15.35
23.56
1.1
Invalid:
24.29
235.215
21.256
To get a integer number between 1 and 23: ^([1-9]|1[0-9]|2[0-3])$
I have a stream of strings representing currency values from where I need to extract integers.
These strings may or may not have characters such as "$", "€", "-", space "." and "," that can alternate to separate decimals and digit groups.
These are the examples of strings and the value that I need to extract from them example:
"1,423,433.00" = 1423433
"1.355,22€" = 1355
" CAD$764.35" = 764
"$734242" = 734242
"$ 234.234,55" = 234234
"545,767$" = 545767
"765 778 00" = 765778
"765.823,888" = 765.823
I tried to use
.replace(/[^\d]/g, '');
but "$ 234.234,55" results is 23423455 and I need 234234 without the decimals. I guess I need to treat the decimals first.
And I also have cases where decimals are separated by "," or "." and can have 3 digits, ex: "1.365.823,803" or "12244.222".
In cases where I have "123.444" what leads me to know that the "." is not for decimals is that the number is never inferior to 10000.
How can I implement a function to extract these numbers?
EDIT:
I think the first step would be to remove all characters except "," or ".".
Than, we can find the decimal symbol, looking for the first symbol from the left.
If it comes after 2 digits, than we know its a decimal symbol.
If it comes after 3 digits, we look for the next symbol to see if it is different.
If it is the same than the first one is not a decimal symbol.
If it is different, than the first one is decimal.
If there's no other symbol, we know the first one is decimal because all numbers are superior to 1000, so if we have 1233.444 we know the "." is the decimals symbol.
If you want to get rid of the decimal part of the number and you a sure always is gonna come after a dot symbol you can use the next set of steps to remove the decimal part and get only the value.
' CAD$764.35'.split('.')[0].replace(/[^\d]/g, ''); // 764
In my opinion a better approach would be to remove all non number/dot characters from the string using replace and a regex, parse the string to a number.
To support all the cases you have, first you must analyze the string and verify which separation symbol is using and adjust the regular expression accordingly. When you use parseInt to coarse the string to a number you don't have to care if the decimal separation symbol is , or ..
parseInt('3452,90') // 3452
parseInt('3452.90') // 3452
But you must remove the other separation symbols from the string or this will cause a bug when you try to parse them.
parseInt('3,452.90') // 3
If I were you, I'd not try to reinvent the wheel. I suggest you a js library called numeral js which can handle the problems with the different currency and decimal formats.
For instance:
numeral("$ 234.234,55")
would output:
234.23455
Check it out for more examples.
You can simply use this
$(document).ready(function(){
myString = "CAD$764.35";
myString = myString.replace ( /[^\d.]/g, '' );
alert(myString);
});
DEMO
What I want is, there is a textbox with maximum length of 5. The values allowed are..
any integer // for example 1, 3, 9, 9239 all are valid
real number, with exaclty one point after decimal // eg. 1.2, 93.7 valid and 61.37, 55.67 invalid
it is also allowed to enter only decimal and a digit after that, that is .7 is valid entry (would be considered as 0.7)
I found this page, http://www.regular-expressions.info/refadv.html
So what I thought is that
There is a digit
If there is a digit and a decimal after that, there must be one number after that
If there is no digit there must be a decimal and a digit after that
So, the regex I made is..
a single digit one or more => /d+
an optional decimal point followed by exactly one digit => (?:[.]\d{1})?
if first condition matches => (?(first condition) => (?((?<=\d+)
then, match the option decimal and one exact digit =>(?((?<=\d+)(?:[.]\d{1})?
else => |
find if there is a decimal and one exact digit => (?:[.]\d{1}){1}
check the whole condition globally => /gm
overall expression =>
(?(?<=\d+)(?:[.]\d{1}){1}|(?:[.]\d{1}){1})+/gm
But it doesn't outputs anything..
Here's the fiddle
http://jsfiddle.net/Fs6aq/4/
ps: the pattern1 and pattern2 there, are related to my previous question.
Maybe you are complicating things too much. I did a quick test and unless I'm missing something this regex seems to work fine:
/^\d*\.?\d$/
Demo: http://jsbin.com/esihex/4/edit
Edit: To check the length you can do it without regex:
if ( value.replace('.','').length <= 5 && regex.test( value ) ) {
...
}
Notice that I used replace to remove the dots so they don't count as characters when getting the length.
You can try the following pattern:
/^\d{0,4}\.?\d$/
It seems to fulfil all your requirements:
> /^\d{0,4}\.?\d$/.test(".4")
true
> /^\d{0,4}\.?\d$/.test(".45")
false
> /^\d{0,4}\.?\d$/.test("1234.4")
true
> /^\d{0,4}\.?\d$/.test("12345.4")
false
> /^\d{0,4}\.?\d$/.test("12345")
true
> /^\d{0,4}\.?\d$/.test("123456")
false
This pattern assumes that the number can have a maximum of five digits and an optional decimal point.
If the maximum length of five includes the optional decimal point then the pattern is slightly more complex:
/^(?:\d{1,5}|\d{0,3}\.\d)$/
The first part of the group deals with integer numbers of the required length, the second option of the group deals with real numbers which maximum length (including the decimal point) is five.
Consider this code:
var checkedString = "45.3 fsd fsd fsdfsd 673.24 fsd63.2ds 32.2 ds 32 ds 44 fasd 432 235f d653 dsdfs";
checkedString = " "+checkedString;
var results = checkedString.match(/[\s]{1}(\d+\.*\d{1})(?![\d\.\w])+/gm);
results.map(function(result) {
return result.trim();
});
Couldn't make it in other way because in JS (?<= (lookbehind) regexp is not working.
This will be returned:
["45.3","32.2","32","44","432"]
So probably it's what you've expected.
I don't know what are you trying to do with those conditionals in your regex. I also looked at your jsfiddle, which outputs nothing for me. But I made a two versions of a regex that matches the correct values for the textbox, which are ^(?!(.{6,}))(?:[1-9]\d*)*(?:\.\d*[1-9])?$ and ^(?!(.{6,}))(?:\d*)*(?:\.\d*)?$.
The first disallows to start with zero, or end with zero after the decimal.
Comment if you need explanation of the regex.
Please help with me writing a JavaScript Validation for currency/money field.
So please provide any regular expressions if u have :)
Also, for my region, don't need any currency symbols like '$' in the field.
Only decimals are to be included for validation as special chars., along with numbers.
You could use a regexp:
var regex = /^\d+(?:\.\d{0,2})$/;
var numStr = "123.20";
if (regex.test(numStr))
alert("Number is valid");
If you're not looking to be as strict with the decimal places you might find it easier to use the unary (+) operator to cast to a number to check it's validity:
var numStr = "123.20";
var numNum = +numStr; // gives 123.20
If the number string is invalid, it will return NaN (Not a Number), something you can test for easily:
var numStr = "ab123c";
var numNum = +numStr;
if (isNaN(numNum))
alert("numNum is not a number");
It will, of course, allow a user to add more decimal places but you can chop any extra off using number.toFixed(2) to round to 2 decimal places. parseFloat is much less strict with input and will pluck the first number it can find out of a string, as long as that string starts with a number, eg. parseFloat("123abc") would yield 123.
I built my answer from the accepted answer.
var regex = /^[1-9]\d*(((,\d{3}){1})?(\.\d{0,2})?)$/;
^[1-9] The number must start with 1-9
\d* The number can then have any number of any digits
(...)$ look at the next group from the end (...)$
(...)?(...)? Look for two groups optionally. The first is for the comma, the second is for the decimal.
(,\d{3}){1} Look for one occurance of a comma followed by exactly three digits
\.\d{0,2} Look for a decimal followed by zero, one, or two digits.
This regex works off of these rules:
Valid values are numbers 0-9, comma and decimal point.
If a customer enters more than one decimal point or more than one comma, the value is invalid and will not be accepted.
Examples of invalid input values
1.2.3
1,2,4
Examples of valid input values
1.23
1,000
3967.
23
1.2
999,999.99
An example can be seen here:
http://jsfiddle.net/rat141312/Jpxu6/1/
UPDATE
by changing the [1-9] in the regex to [0-9] any number less than 1 can also be validated. Example: 0.42, 007
/[1-9]\d*(?:\.\d{0,2})?/
[1-9] - must start with 1 to 9
\d* - any number of other digits
(?: )? - non capturing optional group
\. - a decimal point
\d{0,2} - 0 to 2 digits
does that work for you?
or maybe parseFloat:
var float = parseFloat( input );
let amount = document.querySelector('#amount'), preAmount = amount.value;
amount.addEventListener('input', function(){
if(isNaN(Number(amount.value))){
amount.value = preAmount;
return;
}
let numberAfterDecimal = amount.value.split(".")[1];
if(numberAfterDecimal && numberAfterDecimal.length > 3){
amount.value = Number(amount.value).toFixed(3);;
}
preAmount = amount.value;
})
<input type="text" id="amount">
For me its working fine for Indian currency in INR
var regex = /^[1-9]{0,2}(,{0,1})(\d{2},)*(\d{3})*(?:\.\d{0,2})$/;
var a = '1,111.11';
regex.test(a);
Now I use this:
let func = function (vStr) {
let v0 = Number(vStr);
let v1 = Number(v0.toFixed(2));
return v0 === v1;
};
Note that, NaN === NaN returns false. Maybe some substitution for '$' and ',' before parsing is needed, for other cases.
And there is a problem of precision for very large number, longer than 16 digits. As well as values of '0x3a', '68n' is considered valid.
Nowadays, <input> of type="number", with step='.01' may be more proper.