Regex for numbers with spaces and + sign in front - javascript

If i want to accept only numbers then i will use this regex
^[0-9]*$
but the problem here is that the numbers like
+1 00
are not catched and my regex will show that it is invalid
The user needs to type only numbers but only one space in between is allowed and + sign at the beggining should be optional.
So acceptable is:
+1 11 1 1 11
or
1 11 1 1 11
Unacceptable is:
+1 11 1 1 11
or
1 11 1 1 11
please help

You may try using this regex pattern:
^\+?\d+(?:[ ]?\d+)*$
Sample script:
console.log(/^\+?\d+(?:[ ]?\d+)*$/.test('+1 11 1 1 11')); // true
console.log(/^\+?\d+(?:[ ]?\d+)*$/.test('1 11 1 1 11')); // true
console.log(/^\+?\d+(?:[ ]?\d+)*$/.test('+1 11 1 1 11')); // false
console.log(/^\+?\d+(?:[ ]?\d+)*$/.test('1 11 1 1 11')); // false
The regex pattern used here says to:
^ from the start of the string
\+? match an optional leading +
\d+ then match one or more digits
(?:[ ]?\d+)* followed by an optional single space and more digits,
zero or more times
$ end of the string

Close!
/^[0-9]{1,}$/g
^ = start/first character
[0-9] = Select only number 0-9 but match it once,
{1,} = Match it one or more times,
$ = look no further, so cut all spaces, letters or non matches out!
or even
/^[0-9]+$/g
or even (preferred)
/^-?[1-9]\d*\.?(\d+)?$/g
You should not match anything more but numerals.
function CheckInt(inputNum) {
if (inputNum.toString().match(/^-?[1-9]\d*\.?(\d+)?$/g)) {
console.log(`${inputNum} is a number (INT)`);
} else {
console.log(`${inputNum} is not a number (INT)`);
}
}
CheckInt("a");
CheckInt("b");
CheckInt("c");
CheckInt("102 020");
CheckInt("102-1029");
CheckInt(5400);
CheckInt(-2);
CheckInt(20);
CheckInt(2042992540);

Related

How to match only specific characters in a given string with regex?

I want a specific value, the value be only numbers and:
the length should be 11.
the first digit should be 0.
the second digit should be 1.
the third digit should be 0, 1, 2, 5.
then match any digit from the forth digit to the end.
if the third digit is 1, then the last two digits(10th, 11th) should be the same.
if the third digit is 2, the 8th, 9th digits should be the same.
Input string, and expected result.
01012345678 -----> allowed.
0101234a5678 -----> not allowed., letter exists.
01112345688 -----> allowed, 10th, 11st are the same
01112345677 -----> allowed, 10th, 11st are the same
01112345666 -----> allowed, 10th, 11st are the same
01112345689 -----> not allowed..10th, 11st different
01112345-678 -----> not allowed..hyphen exists.
01298765532 -----> allowed..8th, 9th are the same.
01298765732 -----> not allowed, 8th, 9th different.
01298765mm432 -----> not allowed, letter exists.
01500011122 -----> allowed..
020132156456136 -----> not allowed..more than 11 digit.
01530126453333 -----> not allowed..more than 11 digit.
00123456789 -----> not allowed.. second digit not 1.
This is my attempt at regex101,^01[0125][0-9]{8}$ https://regex101.com/r/cIcD0R/1 but it ignore specific cases also it works for specific cases.
You could make use of an alternation with 2 capture groups and backreferences:
^01(?:[05]\d{8}|1\d{6}(\d)\1|2\d{4}(\d)\2\d\d)$
Explanation
^ Start of string
01 Match literally
(?: Non capture group for the alternatives
[05]\d{8} Match either 0 or 5 and 8 digits
| Or
1\d{6}(\d)\1 Match 1, then 6 digits, capture a single digit in group 1 followed by a backreference to match the same digit
| Or
2\d{4}(\d)\2\d\d Match 2, then 4 digits, capture a single digit in group 2 followed by a backrefence to match the same digit and match the last 2 digits
) Close the non capture group
$ End of string
See a regex101 demo
const regex = /^01(?:[05]\d{8}|1\d{6}(\d)\1|2\d{4}(\d)\2\d\d)$/;
[
"01012345678",
"0101234a5678",
"01112345688",
"01112345677",
"01112345666",
"01112345689",
"01112345-678",
"01298765532",
"01298765732",
"01298765mm432",
"01500011122",
"020132156456136",
"01530126453333",
"00123456789"
].forEach(s => console.log(`${s} => ${regex.test(s)}`))
If you're looking for a regex, purely to filter certain numbers without error messaging, this answer is probably not for you.
For validation purposes, a regex might not be the best way to go. If you would use one giant regex you would show one universal error message. This might leave a user confused since they partially complied with some of the criteria.
Instead split up the criteria so you can show a user relevant error messages.
function isValid(input, criteria) {
const errors = [];
for (const [isValid, error] of criteria) {
if (!isValid(input)) errors.push(error);
}
return [!errors.length, errors];
}
const criteria = [
[input => input.length === 11,
"must have a length of 11"],
[input => input.match(/^\d*$/),
"must only contain digits (0-9)"],
[input => input[0] === "0",
"must have 0 as 1st digit"],
[input => input[1] === "1",
"must have 1 as 2nd digit"],
[input => ["0","1","2","5"].includes(input[2]),
"must have 0, 1, 2 or 5 as 3rd digit"],
[input => input[2] !== "1" || input[9] === input[10],
"the 10th and 11th digit must be the same if the 3rd digit is 1"],
[input => input[2] !== "2" || input[7] === input[8],
"the 8th and 9th digit must be the same if the 3rd digit is 2"],
];
document.forms["validate-number"].addEventListener("submit", function (event) {
event.preventDefault();
const form = event.target;
const inputs = form.elements.inputs.value.split("\n");
inputs.forEach(input => console.log(input, ...isValid(input, criteria)));
});
<form id="validate-number">
<textarea name="inputs" rows="14" cols="15">01012345678
0101234a5678
01112345688
01112345677
01112345666
01112345689
01112345-678
01298765532
01298765732
01298765mm432
01500011122
020132156456136
01530126453333
00123456789</textarea>
<br />
<button>validate</button>
</form>
With your shown samples please try following regex. Here is the Online Demo for used regex.
^01(?:(?:[05][0-9]{8})|(?:1[0-9]{6}([0-9])\1)|(?:2[0-9]{4}([0-9])\2[0-9]{2}))$
Here is the JS code for above regex, using foreach loop along with using test function in it.
const regex = /^01(?:(?:[05][0-9]{8})|(?:1[0-9]{6}([0-9])\1)|(?:2[0-9]{4}([0-9])\2[0-9]{2}))$/;
[
"01012345678",
"0101234a5678",
"01112345688",
"01112345677",
"01112345666",
"01112345689",
"01112345-678",
"01298765532",
"01298765732",
"01298765mm432",
"01500011122",
"020132156456136",
"01530126453333",
"00123456789"
].forEach(element =>
console.log(`${element} ----> ${regex.test(element)}`)
);
Explanation: Adding detailed explanation for used regex.
^01 ##Matching 01 from starting of the value.
(?: ##Starting outer non-capturing group from here.
(?: ##In a non-capturing group
[05][0-9]{8} ##Matching 0 OR 5 followed by any other 8 digits.
)
| ##Putting OR condition here.
(?: ##In a non-capturing group
1[0-9]{6}([0-9])\1 ##Matching 1 followed by 6 digits followed by single digit(in a capturing group) and making sure next digit is matching previous.
)
| ##Puting OR condition here.
(?: ##In a non-capturing group matching, 2 followed by 4 digits followed by 1 digit in capturing group followed by it followed by 2 any other digits.
2[0-9]{4}([0-9])\2[0-9]{2}
)
)$ ##Closing outer non-capturing grouo here at the last of the value.

Regex for decimal prices with or without spaces

I have a problem with my price regex which I'm trying to change. I want it to allow numbers like:
11111,64
2 122,00
123,12
123 345,23
For now I have something like this, but it won't accept numbers without spaces.
'^\d{1,3}( \d{3}){0,10}[,]*[.]*([0-9]{0,2'})?$'
I tried changing ( \d{3}) to (\s{0,1}\d{3}) but it still doesn't work :(
All problems are easier if you break them into pieces.
First we have to match the non decimal
1
100
1 000
10 000 000
The first grouping is 1 to 3 digits or \d{1,3}
We still need to account for the following groups which may or may not be there. That in regex is a * or 0 or many \d{1,3}(\s\d{3})* in that second part we put a space in front of the set to it now looks for spaces between groups of 3.
To complete this set we add in a \d+ for a flat block of numbers
Last we have to match the decimal, optionally ?. ^(\d{1,3}(\s\d{3})*|\d+)(,\d+)?$
/^(\d{1,3}(\s\d{3})*|\d+)(,\d+)?$/.test(str)
Test it some more here: https://regex101.com/r/NKAVLk/1
[
'1',
'123',
'11111,64',
'2 122,00',
'123,12',
'123 345,23',
'2 12,00', // no match, pair of 2 digits
'2 1234,00', // no match, pair of 4 digits
'1,123' // no match, > 2 digits after comma
].forEach(str => {
let t = /^(:?\d{1,3}( \d{3})*|\d+)(,\d{0,2})?$/.test(str);
console.log(str + ' => ' + t);
});
Output:
1 => true
123 => true
11111,64 => true
2 122,00 => true
123,12 => true
123 345,23 => true
2 12,00 => false
2 1234,00 => false
1,123 => false
Explanation of regex:
^ -- anchor at start
(:? -- non-capture group start (for logical OR)
\d{1,3} -- expect 1 to 3 digits
( \d{3})* -- expect 0+ patterns of space and 3 digits
| -- logical OR
\d+ -- expect 1+ digits
) -- non-capture group end
(,\d{0,2})? -- optional pattern of comma and 0 to 2 digits
$ -- anchor at end

Javascript regex for money with max length

I want validate a money string with numbers max length 13 with 2 decimal. I have a comma as decimal separator and a period as a thousands separator.
I have this regex:
/^(\d{1}\.)?(\d+\.?)+(,\d{2})?$/
For sintax is valid but not for max length. What I need to add to this regex?
For example, these strings must be valid:
1.000.000.000.000
1.000.000.000.000,00
1
1,00
123,45
And these must be invalid:
10.000.000.000.000
10.000.000.000.000,00
10.000.000.000.000.000
10.000.000.000.000.000,00
Maybe try to assert position is not followed by 18 digits/dots using a negative lookahead:
^(?![\d.]{18})\d{1,3}(?:\.\d{3})*(?:,\d\d?)?$
See an online demo. Here is assumed you would also allow a single digit decimal.
^ - Open line anchor.
(?![\d.]{18}) - Negative lookahead to prevent 18 digits/dots ahead.
\d{1,3} - One-to-three digits.
(?:\.\d{3})* - A non-capture group of a literal dot followed by three digits with a 0+ multiplier.
(?:,\d\d?)? - Optional non-capture group of a comma followed by either 1 or two digits. Remove the question mark to make the 2nd decimal non-optional.
$ - End line anchor.
You may use this regex for validation:
^(?=[\d.]{1,17}(?:,\d{2})?$)\d{1,3}(?:\.\d{3})*(?:,\d{2})?$
RegEx Demo
RegEx Details:
^: Start
(?=[\d.]{1,17}(?:,\d{2})?$): Lookahead to match dot or digit 1 to 17 times followed by optional comma and 2 digits
\d{1,3}: Match 1 to 3 digits
(?:\.\d{3})*: Match . followed by 3 digits. Repeat this group 0 or more times
(?:,\d{2})?: Match optional , followed 2 decimal digits
$: End
90% of the time there is a better solution than using regex. It's probably best just to convert your strings into a real number then compare vs. your limit (ie 9999999999999.99).
// Pass a string
function convertStr(string) {
/*
Remove all '.'
Replace all ',' with '.'
*/
let numStr = string.split('.').join('').replaceAll(',', '.');
// Convert modified string into a real number
let realNum = parseFloat(numStr);
/*
if converted string is a real number...
round it to two decimal places and return it
Otherwise return false
*/
return !Number.isNaN(realNum) ? Math.round((realNum + Number.EPSILON) * 100) / 100 : false;
}
// Pass a string and the maxed number
function numLimit(string, limit) {
// Get the result of convertString()
let number = convertStr(string);
// if the result is equal to or less than limit...
if (number <= limit) {
return true;
} else {
return false;
}
}
const limit = 9999999999999.99;
const valid = ['1.000.000.000.000',
'1.000.000.000.000,00', '1', '1,00', '123,45'
];
const invalid = ['10.000.000.000.000', '10.000.000.000.000,00', '10.000.000.000.000.000', '10.000.000.000.000.000,00'];
let validResults = valid.map(str => numLimit(str, limit));
let invalidResults = invalid.map(str => numLimit(str, limit));
console.log('valid: ' + validResults);
console.log('invalid: ' + invalidResults);

Regex to support toll free numbers along with UAE numbers

I have a regex that validates UAE numbers like: 00971585045336
here is the regex:
/00971(?:50|51|52|53|54|55|56|57|58|59|2|3|4|6|7|9)\d{7}$/
I have a requirement to add support for toll free numbers like:
0097180038249953 or 0097180022988
I am not good with regex so I need help to make it possible.
Thanks in advance.
You can use the following regex, assuming the tool free number format is 00971800, followed by 5 or 8 digits. Your original regex is simplified with character classes. The test shows 4 valid numbers, followed by invalid numbers:
const regex = /^00971((5\d|[234679])\d{7}|800(\d{5}|\d{8}))$/;
[
'00971581234567',
'0097171234567',
'0097180012345',
'0097180012345678',
'0097158123456',
'009715812345678',
'009717123456',
'00971712345678',
'00971800123456',
'009718001234567',
].forEach((str) => {
let valid = regex.test(str);
console.log(str + ' ==> ' + valid);
});
Output:
00971581234567 ==> true
0097171234567 ==> true
0097180012345 ==> true
0097180012345678 ==> true
0097158123456 ==> false
009715812345678 ==> false
009717123456 ==> false
00971712345678 ==> false
00971800123456 ==> false
009718001234567 ==> false
Explanation:
^ - start of string
00971 - expect literal text
( - start group, used for logical OR
( - start group, used for logical OR
5\d - expect a 5, followed by a digit
| - OR
[234679] - character class with a single char of allowed digits
) - end of group
\d{7} - 7 digits
| - OR
800 - literal text
( - start group, used for logical OR
\d{5} - 5 digits
| - OR
\d{8} - 8 digits
) - end of group
) - end of group
$ - end of string

Javascript regex that matches a decimal that is polluted with other characters

I'm trying to match the first set of digits in the following examples.
some stuff (6 out of 10 as a rating)
needs to return 6
some stuff (2.3 out of 10 as a rating)
needs to return 2.3
some stuff (10 out of 10 as a rating)
needs to return 10
Also, sometimes the string won't have a number
some stuff but nothing else
var match = /\d+(\.\d+)?/.exec("some stuff (10 out of 10 as a rating)");
alert(match[0]);
\d matches any numner, 0-9
+ means 1 or more
\. matches a .
? means 0 or 1
so overall it means any number of digits (0-9) optionally followed by, a decimal point followed by 1 or more digits.
As a function:
var getFirstNumber = function(input){
var match = /\d+(\.\d+)?/.exec(input);
return match[0];
};
You can try this 'some stuff (2.3 out of 10 as a rating)'.match(/\D*(\d\.?(\d)*)/)[1]

Categories

Resources