Как вернуть случайный символ из шаблона регулярных выражений?питон 3 - PullRequest
0 голосов
/ 12 сентября 2018

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

Так вот мой случай ..

Я создал несколько шаблонов регулярных выражений, содержащихся в Enum:

import random
from _operator import invert
from enum import Enum
import re

class RegexExpression(Enum):
    LOWERCASE = re.compile('a-z')
    UPPERCASE = re.compile('A-Z')
    DIGIT = re.compile('\d')
    SYMBOLS = re.compile('\W')

Я хочу, чтобы они возвращались в виде строки, содержащей все символы, которые выражает регулярное выражение, на основе этого метода ниже:

def create_password(symbol_count, digit_count, lowercase_count, uppercase_count):
    pwd = ""
    for i in range(1, symbol_count):
        pwd.join(random.choice(invert(RegexExpression.SYMBOLS.value)))
    for i in range(1, digit_count):
        pwd.join(random.choice(invert(RegexExpression.DIGIT.value)))
    for i in range(1, lowercase_count):
        pwd.join(random.choice(invert(RegexExpression.LOWERCASE.value)))
    for i in range(1, uppercase_count):
        pwd.join(random.choice(invert(RegexExpression.UPPERCASE.value)))
    return pwd

Я пробовал несколько вещей, но единственно возможный вариант - использовать Enum, содержащий длинные шаблоны регулярных выражений или строки, как в следующем примере:

LOWERCASE = "abcdefghijklmnopqrstuvwxyz"

... И так далее с другими используемыми переменными.

Какие-либо предложения или решения для этого сценария?

- EDIT -

Безумный физик принес решение для моей проблемы - Большое спасибо! Вот рабочий код:

def generate_password(length):
     tmp_length = length
     a = random.randint(1, length - 3)
     tmp_length -= a
     b = random.randint(1, length - a - 2)
     tmp_length -= b
     c = random.randint(1, length - a - b - 1)
     tmp_length -= c
     d = tmp_length

     pwd = ""
     for i in range(0, a):
         pwd += random.choice(string.ascii_lowercase)
     for i in range(0, b):
         pwd += random.choice(string.ascii_uppercase)
     for i in range(0, c):
         pwd += random.choice(string.digits)
     for i in range(0, d):
         pwd += random.choice(string.punctuation)

     pwd = ''.join(random.sample(pwd, len(pwd)))
     return pwd

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

В модуле «Секреты» руководства есть рецепт, который может быть более подходящим:

https://docs.python.org/3.6/library/secrets.html#recipes-and-best-practices

from secrets import choice
import string
alphabet = string.ascii_letters + string.digits
while True:
    password = ''.join(choice(alphabet) for i in range(10))
    if (any(c.islower() for c in password)
        and any(c.isupper() for c in password)
            and sum(c.isdigit() for c in password) >= 3):
        break

print(password)
0 голосов
/ 12 сентября 2018

Если вы на 100% настаиваете на использовании регулярных выражений, вам нужна функция для преобразования произвольных классов символов в строки.Я уверен, что есть более простой способ сделать это, но вот процедура общего назначения:

from operator import methodcaller
from re import finditer

UNICODE_MAX = 0xFFFF
UNICODE = ''.join(map(chr, range(UNICODE_MAX + 1)))
ASCII = UNICODE [:128]

def class_contents(pattern, unicode=True, printable=True):
    base = UNICODE if unicode else ASCII
    result = map(methodcaller('group'), finditer(pattern, base))
    if printable:
        result = filter(str.isprintable, result)
    return ''.join(result)

Теперь вы можете просто применить эту функцию к значениям перечисления, чтобы получить строку доступных символов.

Вот ссылка IDEOne для демонстрации результатов: https://ideone.com/Rh4xKI. Обратите внимание, что регулярное выражение для LOWERCASE и UPPERCASE должно быть заключено в квадратные скобки, иначе они будут буквенными трехсимвольными строками, а неклассы персонажей.

0 голосов
/ 12 сентября 2018

Модуль string имеет все необходимые определения.

RegEx не совсем подходит для этой задачи.Выражения используются для проверки, принадлежит ли символ классу.Я не знаю хорошего метода для проверки спецификации символьного класса, не вдаваясь в исходный код / ​​детали реализации.

...