简体   繁体   中英

Regex No Character Should Repeat

I have just started out on the regex part of python and I thought I understood this concept but when I started out the programming I wasn't able to get it. The problem statement which was given is to design a regex which

  1. It must contain at least 2 uppercase English alphabet characters
  2. It must contain at least 3 digits (0-9)
  3. it should only contain alphanumeric characters
  4. No characters should repeat
  5. There must be exactly 10 characters

The code which I wrote is

import re
n=int(input())
patt=r'^(?=.*[A-Z]).{2,}(?=.*[0-9]).{3,}(?=.*[\w]?){10}$'
for x in range(n):
    match=re.findall(patt,str(input()))
    #print(match)
    if match:
        print("Valid")
    else:
        print("Invalid")

I first started out with the 1st part ie should contain " It must contain at least 2 uppercase English alphabet characters " for which I wrote (?=.*[AZ]).{2,} as it will search for more than two characters and will use lookahead assertions For the second part I applied the same and for the third part ie it should only contain alphanumeric characters I applied (?=.*[\\w]?) these three seems to work but when the fourth and fifth condition comes ie No characters should repeat and There must be exactly 10 characters I tried to use {10} at last but it didn't work and the whole thing seems to be broken now. Can anyone guide me how to use regex and what exactly is a positive lookahead.

You may use this regex with 3 lookahead assertions, satisfying all your conditions:

^(?=(?:[a-z\d]*[A-Z]){2})(?=(?:\D*\d){3})(?:([a-zA-Z\d])(?!.*\1)){10}$

RegEx Demo

RegEx Description:

  • ^ : Start
  • (?=(?:[az\\d]*[AZ]){2}) : Lookahead to assert that we have at least 2 uppercase alphabets
  • (?=(?:\\D*\\d){3}) : Lookahead to assert that we have at least 3 digits
  • (?:([a-zA-Z\\d])(?!.*\\1)){10} : Match exact 10 alphanumeric characters. Negative lookahead is to assert that we don't have anything repeating anywhere.
  • $ : End

Read more about look aheads and look behinds

Code:

reg = re.compile(r'^(?=(?:[a-z\d]*[A-Z]){2})(?=(?:.*\d){3})(?:([a-zA-Z\d])(?!.*\1)){10}$')
arr = ['A1b2c3d4eF', 'B1CDEF2354', 'aBcDdef122', 'B1CD102354', 'a1bcf2coqb', 'a1bcf2oo3b', '1234567890']

for i in arr:
      print i, reg.match(i)
import re
n = int(input())
patt = r'^(?=(?:[a-z\d]*[A-Z]){2})(?=(?:\D*\d){3})(?:([a-zA-Z\d])(?!.*\1)){10}$'
for x in range(n):
    match=re.match(patt,str(input()))
    if match:
        print("Valid")
    else:
        print("Invalid")

no characters should repeat condition: regex to match a word with unique (non-repeating) characters

match exact number of characters condition: Regular expression to match exact number of characters?

the must contain condition: Regex must contain specific letters in any order

should contain only condition: it seems from the question you have already figured that out on your own.

The remaining job is to combine them all which you should do on your own if its part of an exercise given to you.

Here is my solution to this question:

import re

for _ in range(int(input())):
    UID = input()
    try:
        assert re.fullmatch(r'[A-Za-z0-9]{10}',UID)
        assert re.fullmatch(r'([a-z0-9]*[A-Z]+[a-z0-9]*){2,}',UID)
        assert re.fullmatch(r'([a-zA-Z]*[0-9]+[a-zA-Z]*){3,}',UID)
        assert not(re.search(r'(.).*?\1',UID))
            
    except AssertionError:
        print('Invalid')
    else:
        print('Valid')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM