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
Related
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.
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)
);
}
I have array of values which I have to separate by their uppercase. But there are some cases where the value of the array has 2, 3 or 4 serial uppercases that I must not separate. Here are some values:
ERISACheckL
ERISA404cCheckL
F401kC
DisclosureG
SafeHarborE
To be clear result must be:
ERISA Check L
ERISA 404c Check L
F 401k C
Disclosure G
Safe Harbor E
I tried using:
value.match(/[A-Z].*[A-Z]/g).join(" ")
But of couse it is not working for serial letters.
One option could be matching 1 or more uppercase characters asserting what is directly to the right is not a lowercase character, or get the position where what is on the left is a char a-z or digit, and on the right is an uppercase char.
The use split and use a capture group for the pattern to keep it in the result.
([A-Z]+(?![a-z]))|(?<=[\da-z])(?=[A-Z])
( Capture group 1 (To be kept using split)
[A-Z]+(?![a-z]) Match 1+ uppercase chars asserting what is directly to the right is a-z
) Close group 1
| Or
(?<=[\da-z])(?=[A-Z]) Get the postion where what is directly to left is either a-z or a digit and what is directly to the right is A-Z
Regex demo
const pattern = /([A-Z]+(?![a-z]))|(?<=[\da-z])(?=[A-Z])/;
[
"ERISACheckL",
"ERISA404cCheckL",
"F401kC",
"DisclosureG",
"SafeHarborE"
].forEach(s => console.log(s.split(pattern).filter(Boolean).join(" ")))
Another option is to use an alternation | matching the different parts:
[A-Z]+(?![a-z])|[A-Z][a-z]*|\d+[a-z]+
[A-Z]+(?![a-z]) Match 1+ uppercase chars asserting what is directly to the right is a-z
| Or
[A-Z][a-z]* Match A-Z optionally followed by a-z to also match single uppercase chars
| Or
\d+[a-z]+ match 1+ digits and 1+ chars a-z
Regex demo
const pattern = /[A-Z]+(?![a-z])|[A-Z][a-z]*|\d+[a-z]+/g;
[
"ERISACheckL",
"ERISA404cCheckL",
"F401kC",
"DisclosureG",
"SafeHarborE"
].forEach(s => console.log(s.match(pattern).join(" ")))
function formatString(str) {
return str.replace(/([A-Z][a-z]+|\d+[a-z]+)/g, ' $1 ').replace(' ', ' ').trim();
}
// test
[
'ERISACheckL',
'ERISA404cCheckL',
'F401kC',
'DisclosureG',
'SafeHarborE'
].forEach(item => {
console.log(formatString(item));
});
I need to create regex which will look for 3 same letters in a string, regardless of the order.
Example:
'aa2ff333' -> false
'aa2a' -> true
'aaa2' -> true
I tried this but it check for consecutive letters:
(.)\1\1
Any advice?
You may use this regex with lookahead:
/([a-zA-Z])(?=(?:.*?\1){2})/
RegEx Demo
RegEx Details:
([a-zA-Z]): Match a letter [a-zA-Z] and capture it in group #1
(?=: Start lookahead
(?:.*?\1){2}: That has at least 2 occurrences of same character as in capture group #1. .*?\1 Matches back-reference \1 after 0 or more of any character. This allows matching repetitions anywhere in input.
): End lookahead
One way is to loop through the string and count occurrence of each character then check if any of character appears for exact three times
let threeChars = (str) => {
let obj = [...str].reduce((op, inp) => {
if (/[a-z]/i.test(inp)) {
op[inp] = op[inp] || 0
op[inp] += 1
}
return op
}, {})
return Object.values(obj).some(v => v === 3)
}
console.log(threeChars('aa2ff333'))
console.log(threeChars('aa2a'))
console.log(threeChars('aaa2'))
P.S:-
You can make it case insensitive by removing the i flag
In case you need to at least 3 character you can change v == 3 to v >= 3
I am looking to accept names in my app with letters and hyphens or dashes, i based my code on an answer i found here
and coded that:
function validName(n){
var nameRegex = /^[a-zA-Z\-]+$/;
if(n.match(nameRegex) == null){
return "Wrong";
}
else{
return "Right";
}
}
the only problem is that it accepts hyphen as the first letter (even multiple ones) which i don't want.
thanks
Use negative lookahead assertion to avoid matching the string starting with a hyphen. Although there is no need to escape - in the character class when provided at the end of character class. Use - removed character class for avoiding - at ending or use lookahead assertion.
var nameRegex = /^(?!-)[a-zA-Z-]*[a-zA-Z]$/;
// or
var nameRegex = /^(?!-)(?!.*-$)[a-zA-Z-]+$/;
var nameRegex = /^(?!-)[a-zA-Z-]*[a-zA-Z]$/;
// or
var nameRegex1 = /^(?!-)(?!.*-$)[a-zA-Z-]+$/;
function validName(n) {
if (n.match(nameRegex) == null) {
return "Wrong";
} else {
return "Right";
}
}
function validName1(n) {
if (n.match(nameRegex1) == null) {
return "Wrong";
} else {
return "Right";
}
}
console.log(validName('abc'));
console.log(validName('abc-'));
console.log(validName('-abc'));
console.log(validName('-abc-'));
console.log(validName('a-b-c'));
console.log(validName1('abc'));
console.log(validName1('abc-'));
console.log(validName1('-abc'));
console.log(validName1('-abc-'));
console.log(validName1('a-b-c'));
FYI : You can use RegExp#test method for searching regex match and which returns boolean based on regex match.
if(nameRegex.test(n)){
return "Right";
}
else{
return "Wrong";
}
UPDATE : If you want only single optional - in between words, then use a 0 or more repetitive group which starts with -as in #WiktorStribiżew answer .
var nameRegex = /^[a-zA-Z]+(?:-[a-zA-Z]+)*$/;
You need to decompose your single character class into 2 , moving the hyphen outside of it and use a grouping construct to match sequences of the hyphen + the alphanumerics:
var nameRegex = /^[a-zA-Z]+(?:-[a-zA-Z]+)*$/;
See the regex demo
This will match alphanumeric chars (1 or more) at the start of the string and then will match 0 or more occurrences of - + one or more alphanumeric chars up to the end of the string.
If there can be only 1 hyphen in the string, replace * at the end with ? (see the regex demo).
If you also want to allow whitespace between the alphanumeric chars, replace the - with [\s-] (demo).
You can either use a negative lookahead like Pranav C Balan propsed or just use this simple expression:
^[a-zA-Z]+[a-zA-Z-]*$
Live example: https://regex101.com/r/Dj0eTH/1
The below regex is useful for surnames if one wants to forbid leading or trailing non-alphabetic characters, while permitting a small set of common word-joining characters in between two names.
^[a-zA-Z]+[- ']{0,1}[a-zA-Z]+$
Explanation
^[a-zA-Z]+ must begin with at least one letter
[- ']{0,1} allow zero or at most one of any of -, or '
[a-zA-Z]+$ must end with at least one letter
Test cases
(The double-quotes have been added purely to illustrate the presence of whitespace.)
"Blair" => match
" Blair" => no match
"Blair " => no match
"-Blair" => no match
"- Blair" => no match
"Blair-" => no match
"Blair -" => no match
"Blair-Nangle" => match
"Blair--Nangle" => no match
"Blair Nangle" => match
"Blair -Nangle" => no match
"O'Nangle" => match
"BN" => match
"BN " => no match
" O'Nangle" => no match
"B" => no match
"3Blair" => no match
"!Blair" => no match
"van Nangle" => match
"Blair'" => no match
"'Blair" => no match
Limitations include:
No single-character surnames
No surnames composed of more than two words
Check it out on regex101.