Struggling with RegEx validation and formating for specfici ID format - javascript

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.

Related

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

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

How to check is string has both letter and number in javascript

I have string "JHJK34GHJ456HJK". How to check if this string has both letter and number, doesn't have whitespace, doesn't have special characters like # - /, If has only letter or only number didn't match.
I try with regex below, result is true if string is only number or letter.
const queryLetterNumber = /^[A-Za-z0-9]*$/.test("JHJK34GHJ456HJK");
const input= [
'JHJK34GHJ456HJK',
'JHJKAAGHJAAAHJK',
'123456789012345',
'JHJK34 space JK',
'JHJK34$dollarJK'
];
const regex = /^(?=.*[0-9])(?=.*[A-Za-z])[A-Za-z0-9]+$/;
input.forEach(str => {
console.log(str + ' => ' + regex.test(str));
});
Output:
JHJK34GHJ456HJK => true
JHJKAAGHJAAAHJK => false
123456789012345 => false
JHJK34 space JK => false
JHJK34$dollarJK => false
Explanation:
^ - anchor at beginning
(?=.*[0-9]) - positive lookahead expecting at least one digit
(?=.*[A-Za-z]) - positive lookahead expecting at least one alpha char
[A-Za-z0-9]+ - expect 1+ alphanumeric chars
$ - anchor at end
you should use a regular expression to check for alphanumeric content in the string
/^[a-z0-9]+$/i
The above is a sample that checks for a-z and numbers from 0-9. however, review other options as given here

How to match 2 separate numbers in Javascript

I have this regex that should match when there's two numbers in brackets
/(P|C\(\d+\,{0,1}\s*\d+\))/g
for example:
C(1, 2) or P(2 3) //expected to match
C(43) or C(43, ) // expect not to match
but it also matches the ones with only 1 number, how can i fix it?
You have a couple of issues. Firstly, your regex will match either P on its own or C followed by numbers in parentheses; you should replace P|C with [PC] (you could use (?:P|C) but [PC] is more performant, see this Q&A). Secondly, since your regex makes both the , and spaces optional, it can match 43 without an additional number (the 4 matches the first \d+ and the 3 the second \d+). You need to force the string to either include a , or at least one space between the numbers. You can do that with this regex:
[PC]\(\d+[ ,]\s*\d+\)
Demo on regex101
Try this regex
[PC]\(\d+(?:,| +) *\d+\)
Click for Demo
Explanation:
[PC]\( - matches either P( or C(
\d+ - matches 1+ digits
(?:,| +) - matches either a , or 1+ spaces
*\d+ - matches 0+ spaces followed by 1+ digits
\) - matches )
You can relax the separator between the numbers by allowing any combination of command and space by using \d[,\s]+\d. Test case:
const regex = /[PC]\(\d+[,\s]+\d+\)/g;
[
'C(1, 2) or P(2 3)',
'C(43) or C(43, )'
].forEach(str => {
let m = str.match(regex);
console.log(str + ' ==> ' + JSON.stringify(m));
});
Output:
C(1, 2) or P(2 3) ==> ["C(1, 2)","P(2 3)"]
C(43) or C(43, ) ==> null
Your regex should require the presence of at least one delimiting character between the numbers.
I suppose you want to get the numbers out of it separately, like in an array of numbers:
let tests = [
"C(1, 2)",
"P(2 3)",
"C(43)",
"C(43, )"
];
for (let test of tests) {
console.log(
test.match(/[PC]\((\d+)[,\s]+(\d+)\)/)?.slice(1)?.map(Number)
);
}

Javascript replace regex to accept only numbers, including negative ones, two decimals, replace 0s in the beginning, except if number is 0

The question became a bit long, but it explains the expected behaviour.
let regex = undefined;
const format = (string) => string.replace(regex, '');
format('0')
//0
format('00')
//0
format('02')
//2
format('-03')
//-3
format('023.2323')
//23.23
format('00023.2.3.2.3')
//23.23
In the above example you can see the expected results in comments.
To summarize. I'm looking for a regex not for test, for replace which formats a string:
removes 0s from the beginning if it's followed by any numbers
allows decimal digits, but just 2
allows negative numbers
allows decimal points, but just one (followed by min 1, max 2 decimal digits)
The last one is a bit difficult to handle as the user can't enter period at the same time, I'll have two formatter functions, one will be the input in the input field, and one for the closest valid value at the moment (for example '2.' will show '2.' in the input field, but the handler will receive the value '2').
If not big favour, I'd like to see explanation of the solution, why it works, and what's the purpose of which part.
Right now I'm having string.replace(/[^\d]+(\.\[^\d{1,2}])+|^0+(?!$)/g, ''), but it doesn't fulfill all the requirements.
You may use this code:
const arr = ['0', '00', '02', '-03', '023.2323', '00023.2.3.2.3', '-23.2.3.2.3']
var narr = []
// to remove leading zeroes
const re1 = /^([+-]?)0+?(?=\d)/
// to remove multiple decimals
const re2 = /^([+-]?\d*\.\d+)\.(\d+).*/
arr.forEach( el => {
el = el.replace(re1, '$1').replace(re2, '$1$2')
if (el.indexOf('.') >= 0)
el = Number(el).toFixed(2)
narr.push(el)
})
console.log(narr)
//=> ["0", "0", "2", "-3", "23.23", "23.23"]
If you aren't bound to the String#replace method, you can try this regex:
/^([+-])?0*(?=\d+$|\d+\.)(\d+)(?:\.(\d{1,2}))?$/
Inspect on regex101.com
It collects the parts of the number into capturing groups, as follows:
Sign: the sign of the number, +, - or undefined
Integer: the integer part of the number, without leading zeros
Decimal: the decimal part of the number, undefined if absent
This regex won't match if more then 2 decimal places present. To strip it instead, use this:
/^([+-])?0*(?=\d+$|\d+\.)(\d+)(?:\.(\d{1,2})\d*)?$/
Inspect on regex101.com
To format a number using one of the above, you can use something like:
let regex = /^([+-])?0*(?=\d+$|\d+\.)(\d+)(?:\.(\d{1,2}))?$/
const format = string => {
try{
const [, sign, integer, decimal = ''] = string.match(regex)
return `${(sign !== '-' ? '' : '-')}${integer}${(decimal && `.${decimal}`)}`
}catch(e){
//Invalid format, do something
return
}
}
console.log(format('0'))
//0
console.log(format('00'))
//0
console.log(format('02'))
//2
console.log(format('-03'))
//-3
console.log(format('023.23'))
//23.23
console.log(format('023.2323'))
//undefined (invalid format)
console.log(format('00023.2.3.2.3'))
//undefined (invalid format)
//Using the 2nd regex
regex = /^([+-])?0*(?=\d+$|\d+\.)(\d+)(?:\.(\d{1,2})\d*)?$/
console.log(format('0'))
//0
console.log(format('00'))
//0
console.log(format('02'))
//2
console.log(format('-03'))
//-3
console.log(format('023.23'))
//23.23
console.log(format('023.2323'))
//23.23
console.log(format('00023.2.3.2.3'))
//undefined (invalid format)
Another option is to use pattern with 3 capturing groups. In the replacement, use all 3 groups "$1$2$3"
If the string after the replacement is empty, return a single zero.
If the string is not empty, concat group 1, group 2 and group 3 where for group 3, remove all the dots except for the first one to keep it for the decimal and take the first 3 characters (which is the dot and 2 digits)
^([-+]?)0*([1-9]\d*)((?:\.\d+)*)|0+$
In parts
^ Start of string
( Capture group 1
[-+]? Match an optional + or -
) Close group
0* Match 0+ times a zero
( Capture group 2
[1-9]\d* Match a digit 1-9 followed by optional digits 0-9
) Close group
( Capture group 3
(?:\.\d+)* Repeat 0+ times matching a dot and a digit
) Close group
| Or
0+ Match 1+ times a zero
$ End of string
Regex demo
const strings = ['0', '00', '02', '-03', '023.2323', '00023.2.3.2.3', '-23.2.3.2.3', '00001234', '+0000100005.0001']
let pattern = /^([-+]?)0*([1-9]\d*)((?:\.\d+)*)|0+$/;
let format = s => {
s = s.replace(pattern, "$1$2$3");
return s === "" ? '0' : s.replace(pattern, (_, g1, g2, g3) =>
g1 + g2 + g3.replace(/(?!^)\./g, '').substring(0, 3)
);
};
strings.forEach(s => console.log(format(s)));

Categories

Resources