Найти - Пользователи
Полная версия: Проверка строкового параметра
Начало » Python для новичков » Проверка строкового параметра
1 2
ice
Доброго времени суток.

Есть функция и параметр, который нужно проверить на валидность.
1: это должна быть строка
2: строка должна быть из 2 или больше символов
3: Символы должны быть строго из списка (для каждой позиции свой список)

Вопрос: как всю эту проверку сделать быстро и красиво? if (.. and .. and) как-то сильно ущербно смотрится ..
как вариант составил все возможные варианты строки в другой список и проверяю if (… in …) но это сильно долго так как список получился не маленький.

Кто-нить сталкивался с такой задачей?
Ferroman
1. Регулярные выражения
2. Цикл + брейк если символ в позиции not in
  • Регулярными - будет быстрее и надёжнее ИМХО.
ice
А как это описать регулярными выражениями? я с циклом сейчас как раз и сделал, но просто интересно как это описать…

например в первой позиции у меня лист из 13 символов
во второй из 4
в третьей, если есть - из 40
и тд. до 6. После 6 допускаются только символы из 6 списка.
Причем там не только буквы, но и цифры и символы специальные.

что-то я даже близко не представляю как это на re сделать.
bialix
на re проверка попадния символа в диапазон делается через '' синтаксис.
Имхо тебе лучше проверка посимвольно

if s in ('a', ‘x’, ‘c’, …)
Ferroman
Сделай не все сразу, а по-частям. Будет понятнее.
Например проверка, соответсвует ли первый символ одному из “abvged” а второй (если не конец строки) “12345”.
import re
print re.compile("^([abvgde])([12345]|$)").match("aw") # ok
print re.compile("^([abvgde])([12345]|$)").match("b") # ok
print re.compile("^([abvgde])([12345]|$)").match("w") # None
print re.compile("^([abvgde])([12345]|$)").match("w1") # None
print re.compile("^([abvgde])([12345]|$)").match("g3") # ok
Вернёт None если строка не соответствует или MatchObject если все “ок”
Ferroman
Имхо тебе лучше проверка посимвольно
А почему?

Хе хе хе 666 пост bialix'а :)
ice
bialix
Имхо тебе лучше проверка посимвольно

if s in ('a', ‘x’, ‘c’, …)
вот как раз так и работает сейчас.

try:
for i in range(len(str)): # у меня 3000 питон, там нет xrange
# тут еще проверка на 6 позицию
……
if str in main_list:
…..
except (….):
….

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

с re тоже попробую, пригодится.
ZAN
Регулярные выражения - намного мощнее, чем что бы там ни было, но, учитывая простоту задачи, можно обойтись без них.
Сложность, фактически, скорее не в реализации, а в задании конфигурации для валидной строки.
Один из вариантов:
import warnings
'''список ниже - конфигураци для валидности строки.
Нулевой позиции соответстует набор символов ‘abc’, второй позиции - ‘abcd’ и т.д.'''
validityList =

def check(validityList, myString):
for index, char in enumerate(myString):
‘'’проверка на валидность посимвольно'''
if char not in validityList:
warnings.warn('invalid char “%s” in position %s' %(char, index))
ice
ZAN, этот вариант мне нравится больше :)

И ведь забыл я совсем про енумирейт

    def check(validityList, myString):
        try:
            for index, char in enumerate(myString):
                '''проверка на валидность посимвольно'''
                j = min (index, 5)
                if char not in validityList[j]:
                    warnings.warn('invalid char "%s" in position %s' %(char, index))
            else:
                if index < 1:
                    warnings.warn('invalid string')
        except (..): # TypeError, NameError
            ...
Вот что-то типа такого и получилось :)
PyCraft
бррррр
ИМХО, регулярка и только регулярка т.к. намного быстрее и намного нагляднее и понятнее
import re

#Назначаем допустимые символы для каждой позиции, можно использовать диапазоны и регулярные выражения
s1="qwer1"
s2="tyui2"
s3="op3"
s4="asdfghjkl4"
s5="zxcvb5"
s6="nm6"
#Компилируем регулярное выражение с предварительным форматированием
rec=re.compile("^([%s])([%s])($|[%s])($|[%s])($|[%s])($|[%s]*)$" % (s1,s2,s3,s4,s5,s6))

#^ - Начало строки
#()- атомарное выражение - символ
#$ - Конец строки
#| - ИЛИ
#[]- список символов применимых в данной позиции
#* - любое количество повторов
#Всего 6 правил, шестое распространяется на все последующие символы до конца строки

#Применяем
print rec.match("q") #None - меньше двух символов
print rec.match("qt") #OK
print rec.match("qto") #OK
print rec.match("qtto") #None - 3символ не входит в список
print rec.match("q6o") #None - 2символ не входит в список
print rec.match("qo") #None - пропустили 2символ и теперь 'o' не входит в список
print rec.match("qto4") #OK
print rec.match("12345") #OK
print rec.match("123456n6m6n") #OK
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB