Reputation: 669
I have been searching a lot through the net and couldn't find a regex that cares for order and other general requirements, my specific need is the following:
I'm working in python, I think I know how to write the regex for 2&3 but didn't find a way to combine 1 since it involves order. Similarly, I know how to write 1 but didn't find a way to combine it with general requirements regex (meaning brackets regex... don't know the name)
For 2 and 3:
^(?=.{6,})(?=.*[\d]).*$
For 1:
^[a-zA-Z].*
Any suggestions?
Upvotes: 0
Views: 116
Reputation: 90752
Start by not assuming that regular expressions are the solution. Then think about the other tools that are available.
Starts with a letter:
word and word[0].isalpha()
(If this test goes after the length one, the word and
bit can be dropped.)
At least six characters long:
len(word) >= 6
At least one digit:
any(letter.isdigit() for letter in word)
This last one is O(n)
for the length of word, though, and if you go for twenty characters without a number it actually ends up slower than the RE solution, because of the string instantiation; you can counter that if long strings with no early numbers will occur regularly with this rather long-winded version:
('0' in word or '1' in word or '2' in word or '3' in word or
'4' in word or '5' in word or '6' in word or '7' in word or
'8' in word or '9' in word)
You can then combine these with ease. Remember with things like this to put it in a separate function with an appropriate docstring; don't put magic calculations in the midst of other unrelated things.
def word_rule_check(word):
'''
Check that the word complies to Rule such-and-such; it must:
1. start with a letter,
2. be at least 6 characters long, and
3. contain at least one digit.
'''
return (len(word) >= 6 and
word[0].isalpha() and
any(letter.isdigit() for letter in word))
Upvotes: 1
Reputation: 1474
Regular expressions aren't very effective at measuring length, just use python len()
for that.
As for the other two conditions, try this:
[a-zA-Z][a-zA-Z0-9]*[0-9][a-zA-Z0-9]*
Upvotes: 0
Reputation: 214969
A general technique to build a "conjunctive" expression that matches A and B and C is to start with ^
and then list conditions as lookahead groups:
^(?=A)(?=B)(?=C)
In your case:
^(?=[A-Za-z])(?=.{6,})(?=\D*\d)
As to the question why this expr doesn't work with $
:
^(?=[A-Za-z])(?=.{6,})(?=\D*\d)$
this is because it doesn't consume any characters, except the virtual "start of input". When you append a $
to it, it becomes equivalent to ^$
, which can only match an empty string.
Upvotes: 7
Reputation: 61525
my specific need is the following:
- Starts with a letter;
- More than 6 characters;
- At least 1 digit.
Never mind regexes then. Test for the properties you want directly.
len(x) > 6 and x[0].isalpha() and any(c.isdigit() for c in x)
Upvotes: 4