user1413824
user1413824

Reputation: 669

i need a regex that cares for order and other general requirements

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:

  1. Starts with a letter;
  2. At least 6 characters;
  3. At least 1 digit.

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

Answers (5)

Chris Morgan
Chris Morgan

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

Peter
Peter

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

georg
georg

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

Prince John Wesley
Prince John Wesley

Reputation: 63698

^(?=.{6,})[a-zA-Z].*\d.*$ is what you need.

Upvotes: 0

Karl Knechtel
Karl Knechtel

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

Related Questions