Regex for decimal prices with or without spaces - javascript

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

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.

How to check character and special character in regex javascript (allow input , and .) [duplicate]

This question already has answers here:
Regular expression to match numbers with or without commas and decimals in text
(11 answers)
Closed 3 months ago.
var regex = /^(?=.*[_$#])(?=.*[^_$#.])[\w$#]$/;
var text = "12a/d";
console.log(regex.test(text))
it's not working.
I want it's allow input only number and float ex: '12.2,2' , '12', '12.2', '2,2'
Thank everyone
I am not clear about your number format examples. Is 12.2,2 two numbers separated by comma? Is 2,2 the German locale representation of a floating number?
Here is a number validation for the English locale with valid and invalid numbers as input:
const input = [
'0',
'1',
'1.',
'1.2',
'-1.2',
'+1.2',
'.123',
'123.45',
'1,123.45',
'123,123.45',
'1,123,123.45',
'', // invalid
'1-2', // invalid
'1+', // invalid
'1x', // invalid
'1,12.9', // invalid
'1,1234.9', // invalid
];
const re = /^[+-]?((\d+|\d{1,3}(,\d{3})+)(\.\d*)?|\.\d+)$/
input.forEach(str => {
console.log( str + ' => ' + re.test(str));
});
Output:
0 => true
1 => true
1. => true
1.2 => true
-1.2 => true
+1.2 => true
.123 => true
123.45 => true
1,123.45 => true
123,123.45 => true
1,123,123.45 => true
=> false
1-2 => false
1+ => false
1x => false
1,12.9 => false
1,1234.9 => false
Explanation of regex:
^ -- anchor at beginning of string
[+-]? -- optional + or -
( -- group 1 start
( -- group 2 start
\d+ -- 1+ digits
| -- logical OR in group 2
\d{1,3}(,\d{3})+ -- 1 to 3 digits, followed by 1+ sets of comma and 3 digits
) -- group 2 end
(\.\d*)? -- optional dot and 0+ digits
| -- logical OR in group 1
\.\d+ -- a dot an 1+ digits
) -- group 1 end
$ -- anchor at end of string

Struggling with RegEx validation and formating for specfici ID format

I have couple specific string formatting i want to achieve for different entities:
Entity 1: 1111-abcd-1111 or 1111-abcd-111111
Entity 2: [10 any symbol or letter(all cap) or number]-[3 letters]
Entity 3: [3 letters all cap]-[3 any]-[5 number]
Not sure if Regex is best approach, because i also want to use this as validator when user starts typing the char's it will check against that Entity selected and then against it's RegEx
Here is a regex with some input strings:
const strings = [
'1111-abcd-1111', // match
'1111-abcd-111111', // match
'1111-abcd-1111111', // no match
'ABCS#!%!3!-ABC', // match
'ABCS#!%!3!-ABCD', // nomatch
'ABC-#A3-12345', // match
'ABC-#A3-1234' // no match
];
const re = /^([0-9]{4}-[a-z]{4}-[0-9]{4,6}|.{10}-[A-Za-z]{3}|[A-Z]{3}-.{3}-[0-9]{5})$/;
strings.forEach(str => {
console.log(str + ' => ' + re.test(str));
});
Result:
1111-abcd-1111 => true
1111-abcd-111111 => true
1111-abcd-1111111 => false
ABCS#!%!3!-ABC => true
ABCS#!%!3!-ABCD => false
ABC-#A3-12345 => true
ABC-#A3-1234 => false
Explanation of regex:
^ - anchor text at beginning, e.g. what follows must be at the beginning of the string
( - group start
[0-9]{4}-[a-z]{4}-[0-9]{4,6} - 4 digits, -, 4 lowercase letters, -, 4-6 digits
| - logical OR
.{10}-[A-Za-z]{3} - any 10 chars, -, 3 letters
| - logical OR
[A-Z]{3}-.{3}-[0-9]{5} - 3 uppercase letters, -, any 3 chars, -, 5 digits
) - group end
$ - anchor at end of string
Your definition is not clear; you can tweak the regex as needed.

Need regex for range values

Need regex for following combination.
Only Numbers
Max 2 digit after decimal
following types of range available
5
8.95
>2.5
<5.65
>=4.24
<=7.2
1.2-3.2
i tried below regex which accept number, two decimal no and should not end with <>=. special characters.
/^(?!.*<>=.$)[0-9]+(\.[0-9]{1,2})?$/gm
Need regex for range values
You could match either a single occurrence of a number preceded by a combination of <>= or match 2 numbers with a hyphen in between.
^(?:(?:[<>]=?)?\d+(?:\.\d{1,2})?|\d+(?:\.\d{1,2})?-\d+(?:\.\d{1,2})?)$
^ Start of string
(?: Non capture group for the alternation
(?:[<>]=?)? Optionally match < > <= >=
\d+(?:\.\d{1,2})? Match 1+ digits with optional decimal part of 1-2 digits
| Or
\d+(?:\.\d{1,2})?-\d+(?:\.\d{1,2})? Match a digits format with a hyphen in between
) Close group
$ End of string
See a regex demo
const pattern = /^(?:(?:[<>]=?)?\d+(?:\.\d{1,2})?|\d+(?:\.\d{1,2})?-\d+(?:\.\d{1,2})?)$/;
[
"5",
"8.95",
">2.5",
"<5.65",
">=4.24",
"<=7.2",
"1.2-3.2",
"1-1.3",
"1-4",
">2",
">=4",
"2.5>",
"1.123"
].forEach(s => console.log(`${s} ==> ${pattern.test(s)}`));
This regex does what you ask for. The test has first some matches, followed by non-matches:
const regex = /^(([><]=?)?[0-9]+(\.[0-9]{1,2})?|[0-9]+(\.[0-9]{1,2})?-[0-9]+(\.[0-9]{1,2})?)$/;
[
'1',
'12',
'12.2',
'12.34',
'>1.2',
'>=1.2',
'<1.2',
'<=1.2',
'1.2-3.4',
'1.22-3.44',
'x1',
'1.234',
'1.222-3.444'
].forEach((str) => {
let result = regex.test(str);
console.log(str + ' ==> ' + result)
})
Output:
1 ==> true
12 ==> true
12.2 ==> true
12.34 ==> true
>1.2 ==> true
>=1.2 ==> true
<1.2 ==> true
<=1.2 ==> true
1.2-3.4 ==> true
1.22-3.44 ==> true
x1 ==> false
1.234 ==> false
1.222-3.444 ==> false

Regex for numbers with spaces and + sign in front

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);

Categories

Resources