Использование регулярных выражений для сопоставления, если определенный символ встречается определенное количество раз

#python #regex

#python #регулярное выражение

Вопрос:

Я пытаюсь использовать регулярные выражения, чтобы проверить, содержит ли строка str по крайней мере два числа и ровно два из следующих символов: ‘!’,’@’,’#’,’$’,’%’,’amp;’,’*’.

Кажется, что происходит то, что я сопоставляю только в том случае, если они встречаются последовательно, а не в целом. Как мне это исправить?

 str = 'a1b2c$3d#4e!f@ghi0'

sym = '[!@#$%amp;*]{2}'
num = '[0-9]{2,}'

for char in str:
    if re.search(sym, str):
        if re.search(num, str):
            print('match!')
        else:
            print('no matches!')
  

Комментарии:

1.Вы могли бы использовать шаблон, подобный ^(?=.*([!@#$%amp;*]).*1)(?=D*dD*d). regex101.com/r/T90MyU/1

2. Попробуйте с помощью sym = «^(.*?[!@#$%amp;*].*?){2}$» и num = «^(.*?\d.*?){2,}$»;

3. Спасибо за ваш вклад, я все еще знакомлюсь с метасимволами в регулярных выражениях.

Ответ №1:

Если вы хотите использовать 2 шаблона, вам не нужно выполнять цикл для проверки каждого символа. В sym вы можете проверить, содержит ли строка ровно 2 из перечисленных символов.

В num вы можете сопоставить не менее 2 цифр.

 import re

str = 'test$test$test123'

sym = r'^[^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*Z'
num = r'^[^drn]*d[^drn]*d'

if re.search(sym, str) and re.search(num, str):
    print('match!')
else:
    print('no matches!')
  

Вы также можете использовать один шаблон с re.match

 ^(?=[^drn]*d[^drn]*d)[^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*Z
  

Объяснение

  • ^ Начало строки
  • (?=[^drn]*d[^drn]*d) Положительный прогноз, утверждение 2 цифр
  • [^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]* Сопоставьте ровно 2 любых из перечисленных символов
  • Z Конец строки

Демонстрация регулярных выражений | Демонстрация Python

 import re

str = 'test$test$test123'
pattern = r'(?=[^drn]*d[^drn]*d)[^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*[!@#$%amp;*][^!@#$%amp;*rn]*Z'
if re.match(pattern, str):
    print('match!')
else:
    print('no matches!')
  

Без использования регулярного выражения одним из вариантов является подсчет вхождений цифры и специальных символов:

 s = 'test$test$test123'
specialChars = "!@#$%amp;*"
num = 0
sym = 0

for char in s:
    if char.isdigit():
        num  = 1
    if char in specialChars:
        sym  = 1

if num > 1 and sym == 2:
    print("Match")
  

Демонстрация Python