1

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.

^(?=.*[A-Z])^(?=.*[a-z])(?=.*\d)(?=.*\d).{8,}$

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]

ilkkachu
  • 138,973
Matt
  • 23
  • 4
    side comment: I hope this is a regex exercise, and not a password policy. – user4556274 Jan 09 '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 09 '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

2 Answers2

2

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
ilkkachu
  • 138,973
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
0

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...

Kusalananda
  • 333,661