JS Regex for full name and phone - javascript

can you help me with regex for :
full name -
can be in english or hebrew [\u0590-\u05FF]-this is the hebrew letter range.
need to be 2 or more words,
that every words contains at least one letter
(doesnt metter the upper or lower case)
Exmaples: Roei Grin, R G, roei grin, r G, roei gr iN,
"רועי גרין","רו ג", רועי גרי ן"
phone number-
must be 10 digits.
must start with 0
can have (not must) the "-" char, in the three or fourth place.
Exmaples: 0549129393, 058-9210348, 0266-391059

Here is a solution for both. Names and numbers have good examples, followed by bad examples:
const testNames = [
'Roei Grin',
'R G',
'roei grin',
'r G',
'roei gr iN',
'רועי גרי ן',
'רו ג',
'רועי גרין',
'Bad'
];
const testNumbers = [
'0549129393',
'058-9210348',
'0266-391059',
'1111',
'011111111',
'0999999-999',
'09999999999'
];
const nameRegex = /^[a-zA-Z\u0590-\u05FF]+( [a-zA-Z\u0590-\u05FF]+)+$/;
const numberRegex = /^0(\d{9}|\d{2}-\d{7}|\d{3}-\d{6})$/;
console.log('testNames:')
testNames.forEach(str => {
console.log('- "' + str + '" ==> ' + nameRegex.test(str));
});
console.log('testNumbers:')
testNumbers.forEach(str => {
console.log('- "' + str + '" ==> ' + numberRegex.test(str));
});
Output:
testNames:
- "Roei Grin" ==> true
- "R G" ==> true
- "roei grin" ==> true
- "r G" ==> true
- "roei gr iN" ==> true
- "רועי גרי ן" ==> true
- "רו ג" ==> true
- "רועי גרין" ==> true
- "Bad" ==> false
testNumbers:
- "0549129393" ==> true
- "058-9210348" ==> true
- "0266-391059" ==> true
- "1111" ==> false
- "011111111" ==> false
- "0999999-999" ==> false
- "09999999999" ==> false
Explanation of nameRegex:
^ ... $ - anchor at start and end of string
[a-zA-Z\u0590-\u05FF]+ - start with 1+ characters of alphabet and/or hebrew
( [a-zA-Z\u0590-\u05FF]+)+ - followed by 1+ pattern of: single space, followed by 1+ characters of alphabet and/or hebrew
Explanation of numberRegex:
^ ... $ - anchor at start and end of string
0 - start with 0
(\d{9}|\d{2}-\d{7}|\d{3}-\d{6}) - followed by either:
9 digits
or 2 digits, -, 7 digits
or 3 digits, -, 6 digits

You can use, this reg exp for your mask phone - ^[0]{1}(([\d]{2}[-]{0}[\d]{7})|([\d]{3}[-]{1}[\d]{6})|([\d]{2}[-]{1}[\d]{7}))

Related

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.

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

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 to validate a comma separated list of unique numbers

I am trying to validate a comma separated list of numbers 1-7 unique (not repeating).
i.e.
2,4,6,7,1 is valid input.
2,2,6 is invalid
2 is valid
2, is invalid
1,2,3,4,5,6,7,8 is invalid ( only 7 number)
I tried ^[1-7](?:,[1-7])*$ but it's accepting repeating numbers
var data = [
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(function(str) {
document.write(str + ' gives ' + /(?!([1-7])(?:(?!\1).)\1)^((?:^|,)[1-7]){1,7}$/.test(str) + '<br/>');
});
Regex are not suited for this. You should split the list into an array and try the different conditions:
function isValid(list) {
var arrList = list.split(",");
if (arrList.length > 7) { // if more than 7, there are duplicates
return false;
}
var temp = {};
for (var i in arrList) {
if (arrList[i] === "") return false; // if empty element, not valid
temp[arrList[i]] = "";
}
if (Object.keys(temp).length !== arrList.length) { // if they're not of same length, there are duplicates
return false;
}
return true;
}
console.log(isValid("2,4,6,7,1")); // true
console.log(isValid("2,2,6")); // false
console.log(isValid("2")); // true
console.log(isValid("2,")); // false
console.log(isValid("1,2,3,4,5,6,7,8")); // false
console.log(isValid("1,2,3")); // true
console.log(isValid("1,2,3,7,7")); // false
No RegEx is needed:
This is much more maintainable and explicit than a convoluted regular expression would be.
function isValid(a) {
var s = new Set(a);
s.delete(''); // for the hanging comma case ie:"2,"
return a.length < 7 && a.length == s.size;
}
var a = '2,4,6,7,1'.split(',');
alert(isValid(a)); // true
a = '2,2,6'.split(',');
alert(isValid(a)); // false
a = '2'.split(',');
alert(isValid(a)); // true
a = '2,'.split(',');
alert(isValid(a)); // false
'1,2,3,4,5,6,7,8'.split(',');
alert(isValid(a)); // false
You were pretty close.
^ # BOS
(?! # Validate no dups
.*
( [1-7] ) # (1)
.*
\1
)
[1-7] # Unrolled-loop, match 1 to 7 numb's
(?:
,
[1-7]
){0,6}
$ # EOS
var data = [
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(function(str) {
document.write(str + ' gives ' + /^(?!.*([1-7]).*\1)[1-7](?:,[1-7]){0,6}$/.test(str) + '<br/>');
});
Output
2,4,6,7,1 gives true
2,2,6 gives false
2 gives true
2, gives false
1,2,3,2 gives false
1,2,2,3 gives false
1,2,3,4,5,6,7,8 gives false
For a number range that exceeds 1 digit, just add word boundary's around
the capture group and the back reference.
This isolates a complete number.
This particular one is numb range 1-31
^ # BOS
(?! # Validate no dups
.*
( # (1 start)
\b
(?: [1-9] | [1-2] \d | 3 [0-1] ) # number range 1-31
\b
) # (1 end)
.*
\b \1 \b
)
(?: [1-9] | [1-2] \d | 3 [0-1] ) # Unrolled-loop, match 1 to 7 numb's
(?: # in the number range 1-31
,
(?: [1-9] | [1-2] \d | 3 [0-1] )
){0,6}
$ # EOS
var data = [
'2,4,6,7,1',
'2,2,6',
'2,30,16,3',
'2,',
'1,2,3,2',
'1,2,2,3',
'1,2,3,4,5,6,7,8'
];
data.forEach(function(str) {
document.write(str + ' gives ' + /^(?!.*(\b(?:[1-9]|[1-2]\d|3[0-1])\b).*\b\1\b)(?:[1-9]|[1-2]\d|3[0-1])(?:,(?:[1-9]|[1-2]\d|3[0-1])){0,6}$/.test(str) + '<br/>');
});
Like other commenters, I recommend you to use something other than regular expressions to solve your problem.
I have a solution, but it is too long to be a valid answer here (answers are limited to 30k characters). My solution is actually a regular expression in the language-theory sense, and is 60616 characters long. I will show you here the code I used to generate the regular expression, it is written in Python, but easily translated in any language you desire. I confirmed that it is working in principle with a smaller example (that uses only the numbers 1 to 3):
^(2(,(3(,1)?|1(,3)?))?|3(,(1(,2)?|2(,1)?))?|1(,(3(,2)?|2(,3)?))?)$
Here's the code used to generate the regex:
def build_regex(chars):
if len(chars) == 1:
return list(chars)[0]
return ('('
+
'|'.join('{}(,{})?'.format(c, build_regex(chars - {c})) for c in chars)
+
')')
Call it like this:
'^' + build_regex(set("1234567")) + "$"
The concept is the following:
To match a single number a, we can use the simple regex /a/.
To match two numbers a and b, we can match the disjunction /(a(,b)?|b(,a)?)/
Similarily, to match n numbers, we match the disjunction of all elements, each followed by the optional match for the subset of size n-1 not containing that element.
Finally, we wrap the expression in ^...$ in order to match the entire text.
Edit:
Fixed error when repeating digit wasn't the first one.
One way of doing it is:
^(?:(?:^|,)([1-7])(?=(?:,(?!\1)[1-7])*$))+$
It captures a digit and then uses a uses a look-ahead to make sure it doesn't repeats itself.
^ # Start of line
(?: # Non capturing group
(?: # Non capturing group matching:
^ # Start of line
| # or
, # comma
) #
([1-7]) # Capture digit being between 1 and 7
(?= # Positive look-ahead
(?: # Non capturing group
, # Comma
(?!\1)[1-7] # Digit 1-7 **not** being the one captured earlier
)* # Repeat group any number of times
$ # Up to end of line
) # End of positive look-ahead
)+ # Repeat group (must be present at least once)
$ # End of line
var data = [
'2,4,6,7,1',
'2,2,6',
'2',
'2,',
'1,2,3,4,5,6,7,8',
'1,2,3,3,6',
'3,1,5,1,8',
'3,2,1'
];
data.forEach(function(str) {
document.write(str + ' gives ' + /^(?:(?:^|,)([1-7])(?=(?:,(?!\1)[1-7])*$))+$/.test(str) + '<br/>');
});
Note! Don't know if performance is an issue, but this does it in almost half the number of steps compared to sln's solution ;)

Regex to restrict certain numbers but allow all others

I want a regex to allow only numbers except certain numbers
example: Restrict 101 - 109. All others are allowed
Tried
var regex = new RegExp(/^([0-9]+|[^10[1-9]]| [^0])$/);
regex.test(101) // should give false
regex.test(109) // should give false
regex.test(0) // should give false
Any other value should give true
regex.test(100001) // should give true
This does not work
You can use a negative lookahead based regex to disallow certain numbers while matching all numbers:
/^(?!(0|10[1-9])$)\d+$/
RegEx Demo
(?!(0|10[1-9])$) is negative lookahead to disallow 0, and all numbers from 101-109.
Try this:
!/^0|10[1-9]$/.test(101)
function check_number(n){
return !/^0|10[1-9]$/.test(n);
}
document.write('101 : ' + check_number(101) + '<br>');
document.write('109 : ' + check_number(109) + '<br>');
document.write('0 : ' + check_number(0) + '<br>');
document.write('100001 : ' + check_number(100001) + '<br>');
Example: This restricts it to 238 - 971
This is just showing that its not the restriction that is hard,
its generating a number range regex.
A good tool that does it for you is here.
^(?!0*(?:23[8-9]|2[4-9]\d|[3-8]\d{2}|9[0-6]\d|97[0-1])$)\d+$
Expanded
^
(?!
0*
(?:
23 [8-9]
| 2 [4-9] \d
| [3-8] \d{2}
| 9 [0-6] \d
| 97 [0-1]
)
$
)
\d+
$

Categories

Resources