2016-02-19 2 views
3

У меня есть модель:Джанго регулярное выражение в поле

class M(Model): 
    re = CharacterField(max_length=50, blank=true) 

Например, в таблице у меня есть:

table m 
---------------- 
| id | re | 
---------------- 
| 1 | \d+ | 
| 2 | \:abc | 
---------------- 

Я хочу, чтобы найти какой-то объект, который будет соответствовать моей входной строки (inp) с помощью регулярных выражений хранятся в re поле, смотри пример:

inp = ":abc" 
for m in M.objects.all(): 
    if re.match(m.re, inp) 
     print("{} matched".format(m.id)) # 2 matched 

Но можно выполнить match на сервере БД? Итак, замените .all() на «.filter» с некоторым выражением?

ответ

0
for m in M.objects.filter().extra(where=["'{}' RLIKE `m`.`re`".format(inp)]) 
    print("{} matched".format(m.id)) 
2

Для регулярного выражения соответствия необходимо использовать __iregex после имя_поля в filter вызова:

M.objects.filter(re__iregex=inp) 

Взгляните на official documentation, чтобы получить больше информации


EDIT

If вам нужна обратная операция (чтобы проверить, соответствует ли какое-либо регулярное выражение в базе данных г ваше значение) вы не можете использовать простые filter но вы можете определить свой пользовательский Manager

class CurrentManager(models.Manager): 
    def match(self, value): 
     objects = super(CurrentManager, self).get_query_set().all() 

     #here your code 
     objects = [o for o in objects if re.match(o, value)] 

     return objects 

class M(Model): 
    re = CharacterField(max_length=50, blank=true) 
    objects = RegexManager() 

#usage 
matched = M.objects.match('123') 

Взгляните на эту question также.

+0

'iregex' работает в прямом направлении - когда столбцу в таблице согласовано с некоторым регулярным выражением, мне нужно реверсировать операцию - какое-то значение для регулярных выражений согласованнога в столбце. Я попробовал 'M.objects.filter (re__iregex =" 123 "). First()' и он возвращает 'None', но должен возвращать' 1', потому что '123' соответствует под' \ d + ' – user3479125

+1

взгляните на мое редактирование –

+0

спасибо, это интересное и информативное решение, один вопрос: будет ли он сначала выбрать все из db, а затем найти совпадающий объект в python? Моя цель - выполнить регулярное совпадение на сервере БД (я думаю, что выборка всех исходных данных с сервера БД будет неэффективной, если в таблице будет много строк). Кажется, что django не имеет такого фильтра, поэтому мне нужно применить некоторые дополнительные условия к 'where', что-то вроде' 'WHERE {} REGEXP m.re'.format (inp)', я попробую его позже. – user3479125

2

Во-первых, \d не обрабатывается MySQL. Вместо этого используйте [0-9] или [[:digit:]].

Во-вторых, чтобы сделать регулярное выражение SQL, есть приложение построить

'[0-9]+|:abc' 

, а затем построить, что в запросе.

Но вы, вероятно, хотите, чтобы закрепить регулярное выражение:

'^([0-9]+|:abc)$' 
+0

спасибо за уведомление о '\ d', я использую сервер MariaDB, который должен поддерживать регулярные выражения PCRE.Моя задача - найти, какая строка в таблице 'm' хранит' re', которая соответствует некоторой входной строке, может быть много строк, введенных системным администратором, и у них могут быть разные выражения - 2 строки очень упрощены, чтобы упростить вопрос, которые не имеют практической ценности, только технические. – user3479125

Смежные вопросы