Django - хранение необработанного строкового литерала в модели для использования в регулярных выражениях? - PullRequest
2 голосов
/ 14 октября 2011

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

class Foo(models.Model):
    name = models.CharField(max_length=30, unique=True)
    regex_string = models.TextField()

Так, например, поле regex_string может быть установлено на:

r'\d{2}'

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

>>> pattern = re.compile(ham.regex_string)
>>> print(pattern.match("22"))
None

Очевидно, если я передамнепосредственный литерал строки, он работает нормально:

>>> pattern = re.compile(r'\d{2}')
>>> pattern.match("22")
<_sre.SRE_Match object at 0x1505100>

Если я на самом деле печатаю ham.regex_string, он возвращает:

u"r'\\d{2}'"

Так что это строка в юникоде, но по какой-то причинеобратные слеши удвоены?Есть ли лучший способ сохранить шаблон регулярного выражения в модели Django, чтобы я мог использовать его позже?

Приветствия, Виктор

РЕДАКТИРОВАТЬ: Спасибо всем за ответы =).Я присудил ответ rczajka, так как он был первой частью поста (по крайней мере, если верить временным меткам StackOverflow).

Просто, чтобы прояснить ситуацию, поле было введено пользователями в форме(Джанго-администратор).Ранее они вводили регулярные выражения с r'' - например, r'\d{2}\.Однако, если я просто заставлю их ввести в строковый литерал сам \d{2}, теперь это, похоже, сработает - Django не изменяет строку и не интерпретирует обратную косую черту - нет никаких причин для этого, верно?

Ответы [ 4 ]

2 голосов
/ 14 октября 2011

Вам просто нужно быть умнее после извлечения.

>>> import ast
>>> print ast.literal_eval(u"r'\\d{2}'")
\d{2}
1 голос
/ 14 октября 2011

Э-э, не храните литерал (т. Е. "r'\d{2}'"), сохраняйте то, что он дает.

foo    = Foo.objects.create(regex_string = r'\d{2}')
foo_re = re.compile(foo.regex_string)
0 голосов
/ 14 октября 2011

Как установить поле regex_string?Возможно, вы вводите вклад на странице?Обозначение r'' является просто синтаксическим сахаром:

>>> r'\d{2}'
'\\d{2}'
>>> print r'\d{2}'
\d{2}

Так что, если вы хотите поместить что-то во вход, напишите фактическую строку регулярного выражения (\d{2}), а не литерал Python.

0 голосов
/ 14 октября 2011

Это действительно странная ошибка. Необработанная строка Python - это просто синтаксическое удобство (оно оценивается как обычная строка байтов), поэтому я не вижу, как вообще возможно получить u"r'\\d{2}". Все, о чем я могу думать, это то, что вы как-то написали двойные кавычки вокруг литерала, что не является вероятной ошибкой.

Когда я бегу

from someproject.someapp.models import *
ham = Foo(name=u'test', regex_string=r'\d{2}')
ham.save()
ham = Foo.objects.get(name=u'test')
print ham.regex_string

в manage.py shell, я получаю строку Unicode \d{2} (как и ожидалось).

Вы сказали, что напечатали ham.regex_string, но похоже, что вы только что оценили его в интерактивной консоли Python. Это дает объекту repr, который в данном случае равен u'\\d{2}'. Удвоенный \\ только для отображения; строка на самом деле содержит один \.

Кроме того: вы на самом деле используете регулярное выражение для сопоставления двоичных строк? Если нет, то вместо этого вы должны использовать регулярное выражение Unicode ur'\d{2}'. Если это так, вам следует явно закодировать в Base64 свое регулярное выражение, поскольку в общем случае двоичное регулярное выражение является недопустимым UTF-8 и, следовательно, не будет правильно храниться в базе данных.

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