I need a regular expression to meet the criteria for a basic password policy.

1st character is a capital ends with 2 digits is 8 characters long

Here is what I have so far.


It meets the criteria i want e.g. Passwo12 but also matches

Passw123 (unacceptable)
Pa234567 (unacceptable)

I want it to be restricted to specifically [capital] [lowercase [a-z] x5] [digit x2]

  • 4
    side comment: I hope this is a regex exercise, and not a password policy. – user4556274 Jan 9 '18 at 20:18
  • I do wonder, where ever did you come up with the idea of using the (?=...) construct there? Do you know what it does? As a Perl RE, that matches e.g. something like 1xxxxxxX. – ilkkachu Jan 9 '18 at 22:35
  • Yeah its a simple exercise to help me learn regex. Not going into a real world practice otherwise it would be much stronger and more complicated. I had absolutely no idea what the ((?-...) look ahead construct)) was until i researched it. I copied the above code from another post and altered it to try and make it fit my criteria. – Matt Jan 11 '18 at 12:53

I'd suggest something like:

grep -E '^[[:upper:]][[:lower:]]{5}[[:digit:]]{2}$' input

or with Bash's [[ .. ]] conditional:

[[ $pass =~ ^[[:upper:]][[:lower:]]{5}[[:digit:]]{2}$ ]] && echo OK
  • ^[[:upper:]][[:lower:]]{5}[[:digit:]]{2}$ Works perfectly thank you for being so quick :) – Matt Jan 9 '18 at 20:19
  • @dhag, you're quite right. See e.g. here if you still feel confused. – ilkkachu Jan 9 '18 at 22:34

Do one test for each criteria, that will make it easier to maintain and to extend.

  1. First character is a capital letter: ^[[:upper:]]
  2. Last two characters are digits: [[:digit:]][[:digit:]]$
  3. Length is 8 characters: ^.{8}$
  4. Other characters are lower-case (not explicitly stated): ^.[[:lower:]]*..$

With sed (will only let through passwords matching the above criteria):

sed -r \
    -e '/^[[:upper:]]/!d' \
    -e '/[[:digit:]][[:digit:]]$/!d' \
    -e '/^.{8}$/!d' \
    -e '/^.[[:lower:]]*..$/!d'

This way you may easily add other criteria or modify the existing ones (more or less) independently of the others.

The -r is to allow for the extended regular expression in criteria #3.

sed thing that will comment on the ways that passwords fail the criteria:

sed -r \
    -e '/^[[:upper:]]/!a\
No initial upper-case
' \
    -e '/[[:digit:]][[:digit:]]$/!a\
No trailing digits
' \
    -e '/^.{8}$/!a\
Not 8 characters
' \
    -e '/^.[[:lower:]]*..$/!a\
Not only lower-case middle chars

You can't do that if you cram everything into a single regular expression...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.