Регулярное выражение не учитывает минимальное / максимальное значение должным образом - PullRequest
0 голосов
/ 22 января 2019

edit: я упростил свое регулярное выражение, чтобы получить правильный вывод (см. Ответ ниже).Я все еще хотел бы совет, почему рассматриваемое регулярное выражение не работает.

Я пытаюсь проверять данные из файла .csv, строка за строкой.Если это соответствует заданному параметру, отлично.Если нет, то плохо.Рассматриваемая строка - это строка username.Первый if проверяет, как следует, а второй elif нет (что и задумано).

Я думаю, что значение для matchObj должно быть допустимым только в рамках операторов if,но я также пытался установить matchObj = None перед запуском .match, но все равно не выдает правильный вывод.

Я приложил весь свой код для справки.Я кодирую это в Python3.Извините за потенциальный тупой вопрос, я пришел из Java / C.

import re

with open("input.csv", "r") as insert:
array = []
for line in insert:
    array.append(line)

for i in range(len(array)):
    tempList = array[i].split(',')
    print(tempList[0])

    if tempList[0] == 'student':
        matchObj = re.match('\d{3}[\s]?\d{3}[\s]?\d{3}', tempList[1])
        if matchObj:
            print('student = Right!')
    elif tempList[0] == 'password':
        matchObj = re.match('(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{12,}', tempList[1])
        if matchObj:
            print('password = Right!')
    elif tempList[0] == 'username':
        matchObj = re.match('(?=.*[a-z])(?=.*[A-Z]).{3,20}', tempList[1])
        print(matchObj)
        print(tempList[0])
        print(tempList[1])
        if matchObj:
            print('username = Right!')

Третий elif для username должен вернуть «Верно!».Он может содержать любой символ AZ, регистр не имеет значения или любую цифру.Должно быть от 3 до 20 символов.Пример ввода в моем .csv user123

Вот .csv

student,999999999
password,abcd1234
username,user123

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Давайте посмотрим на само ваше регулярное выражение: (?=.*[a-z])(?=.*[A-Z]).{3,20}

Насколько я могу судить, это то, что делают разные группы:

  • (?=.*[a-z]) - Предварительное утверждение для любого символа (кроме новой строки), повторяемое любое количество раз, за ​​которым следует строчная буква.
  • (?=.*[A-Z]) - сделать предварительное утверждение для любого символа (кроме новой строки), повторенное любое количество раз, за ​​которым следует заглавная буква.
  • . - Следите за любым другим символом рядом, который не является новой строкой.
  • {3,20} - сопоставить этот предыдущий символ от 3 до 20 раз

Поэтому, когда я запускаю это, например:

test_strings = [ 'Papa', 'papa', 'pA', 'pA!', 'pa&Pa', 'pApa', 'pa\nPa' ]
for s in test_strings:
    m = re.match('(?=.*[a-z])(?=.*[A-Z]).{3,20}', s)
    if m:
        print('"%s" is good' % s)
    else:
        print('"%s" is BAD' % s)

Я получаю эти результаты:

"Papa" is good
"papa" is BAD
"pA" is BAD
"pA!" is good
"pa&Pa" is good
"pApa" is good
"pa
   Pa" is BAD

Но если все, что вы действительно хотите сделать, это убедиться, что tempList[1] - это строка, состоящая только из буквенно-цифровых символов, тогда упрощенное регулярное выражение, которое вы задаете в качестве ответа, имеет больше смысла. Фактически, поскольку вы сопоставляете всю строку, ^ и $ кажутся избыточными.

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

matchObj = tempList[1].isalnum() and len(tempList[1]) in range(3,21)
0 голосов
/ 22 января 2019

Я упростил свое регулярное выражение, чтобы оно заработало.

^[a-zA-Z0-9]{3,20}$

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...