Reputation: 69
I'm trying to use regex that checks a string for alphabets and numbers, but it shouldn't match if the string contains only alphabets. This is for a javascript code. Should lookahead be used?
Should match: 1234567 a1b2c3d4e5 1a2b3c4d5e
Should not match: abcdefg
EDIT: Thanks to @balsick this question has been answered. Here's the regex to be used - (([a-zA-Z0-9]+\d+[a-zA-Z0-9])|(\d+[a-zA-Z0-9]+\d))+
I do have a follow-up question: can a length constraint be added to this regex? For example: I want to match only strings that are 10-20 alphabets/digits.
Upvotes: 1
Views: 1067
Reputation: 163362
You could assert the start of the string ^
, use a non capturing group (?:
with an alternation to match either a digit \d
or |
one or more characters followed by a digit [a-z]+\d
. This makes sure that you have at least 1 digit and that you could also start with characters.
Then for the last part of the regex you could match zero or more digits and characters [a-z\d]*
until the end of the string $
.
To match upper and lowercase characters you could use [a-z]
with the case insensitive flag /i
let pattern = /^(?:\d|[a-z]+\d)[a-z\d]*$/i;
const strings = [
"a1b2c3d4e5",
"1a2b3c4d5e",
"abcdefg",
"1234567"
];
strings.forEach((s) => {
console.log(s + " ==> " + pattern.test(s));
});
If you want to make sure that your match contains 10 - 20 alphanumeric characters you could use a positive lookahead:
^(?=[a-z\d]*\d)[a-z\d]{10,20}$
let pattern = /^(?=[a-z\d]*\d)[a-z\d]{10,20}$/i;
const strings = [
"a1b2c3d4e5",
"1a2b3c4d5e",
"1234567",
"abcdefg",
"1234567",
"12112121121fffdfdfdfdfdfdfd",
"fdfddfdfdffdfdf5ffrtgr54f345f453f3ff"
];
strings.forEach((s) => {
console.log(s + " ==> " + pattern.test(s));
});
Upvotes: 2
Reputation: 830
Try this:
((\w+\d+\w*)|(\d+\w+\d*))+
\w looks for alphabetic
\d looks for digits
+ means at least one
* means zero or more
| is the or operator
I have found a better solution for your primary question. It is shorter and faster than the solution of @balsick and it won't catch the _
character:
([a-zA-Z]*\d[a-zA-Z]*)+
Your wish to limit the length of strings is hard to conquer with regex. There are options to limit the number of matches. For example with:
a{5}
, a{2,}
exactly five, two or more
a{1,3}
between one & three
But this won't work with the upper regex, because each single submatch will be either
If you have an match like a1b2c3d4e5
it consists out of these submatches: a1b
2c
3d
4e
5
Although the match consists out of 10 characters, using the quantifier {10,20}
instead of the last plus sign won't work, because the real number of submatches would be 5 and not 10.
I think you have to use the upper regex and after that check the length of each match programatically afterwords.
Pseudo code:
foreach (var match in matches) {
if (match.Value.length < 21 && match.Value.length > 9) {
doSomething();
}
}
Or if you have the possibility to use Linq you could do something like this:
var filteredMatches = matches.Filter(match => match.Value.length < 21 && match.Value.length > 9)
Upvotes: 4