Форум сайта python.su
Доброго времени суток.
Есть функция и параметр, который нужно проверить на валидность.
1: это должна быть строка
2: строка должна быть из 2 или больше символов
3: Символы должны быть строго из списка (для каждой позиции свой список)
Вопрос: как всю эту проверку сделать быстро и красиво? if (.. and .. and) как-то сильно ущербно смотрится ..
как вариант составил все возможные варианты строки в другой список и проверяю if (… in …) но это сильно долго так как список получился не маленький.
Кто-нить сталкивался с такой задачей?
Офлайн
1. Регулярные выражения
2. Цикл + брейк если символ в позиции not in
Отредактировано (Июнь 25, 2008 13:55:11)
Офлайн
А как это описать регулярными выражениями? я с циклом сейчас как раз и сделал, но просто интересно как это описать…
например в первой позиции у меня лист из 13 символов
во второй из 4
в третьей, если есть - из 40
и тд. до 6. После 6 допускаются только символы из 6 списка.
Причем там не только буквы, но и цифры и символы специальные.
что-то я даже близко не представляю как это на re сделать.
Офлайн
на re проверка попадния символа в диапазон делается через '' синтаксис.
Имхо тебе лучше проверка посимвольно
if s in ('a', ‘x’, ‘c’, …)
Офлайн
Сделай не все сразу, а по-частям. Будет понятнее.
Например проверка, соответсвует ли первый символ одному из “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
Отредактировано (Июнь 25, 2008 14:33:14)
Офлайн
Имхо тебе лучше проверка посимвольноА почему?
Офлайн
bialixвот как раз так и работает сейчас.
Имхо тебе лучше проверка посимвольно
if s in ('a', ‘x’, ‘c’, …)
Отредактировано (Июнь 25, 2008 15:22:17)
Офлайн
Регулярные выражения - намного мощнее, чем что бы там ни было, но, учитывая простоту задачи, можно обойтись без них.
Сложность, фактически, скорее не в реализации, а в задании конфигурации для валидной строки.
Один из вариантов:
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))
Отредактировано (Июнь 25, 2008 15:49:06)
Офлайн
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 ...
Отредактировано (Июнь 26, 2008 09:22:16)
Офлайн
бррррр
ИМХО, регулярка и только регулярка т.к. намного быстрее и намного нагляднее и понятнее
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
Отредактировано (Июнь 26, 2008 12:59:25)
Офлайн