2013-02-21 18 views
8

Próbuję napisać zapytanie Django, które będzie pasowało tylko do całych słów. Na podstawie odpowiedzi here, próbowałem coś takiego:Dopasowanie całego słowa tylko w zapytaniu Django

result = Model.objects.filter(text__iregex='\bsomeWord\b') 

Ale to nie zwraca oczekiwanego rezultatu. Próbowałem także

bezskutecznie. Mój koniec celem jest być w stanie przekazać w zmiennej łańcuchowej, jak również, podobnie jak:

result = Model.objects.filter(text__iregex=r'\b'+stringVariable+r'\b') 

lub

result = Model.objects.filter(text__iregex=r'\b %s \b'%stringVariable) 

ale teraz nawet nie mogę zmusić go do pracy z surowego sznurka . Używam PostgreSQL.

+0

Jaką bazę danych używasz? – Matt

+0

@MattStevens, używam PostgreSQL. – GChorn

Odpowiedz

11

użyć „\ y” zamiast „\ b”, gdy używasz PostgreSQL, to dlatego, Django przechodzi wyrażenia regularnego prosto w dół do PostgreSQL - tak potrzebujemy Twojej regex, aby być z nim zgodne. Powinieneś być w stanie wykonać je z psql bez żadnych problemów.

result = Model.objects.filter(text__iregex=r"\y{0}\y".format(stringVariable)) 

Patrz: http://bit.ly/ZtpojU

+1

Czym dokładnie jest '\ y'? –

+0

Django nie wykonuje żadnego tłumaczenia PCRE na wyrażenia regularne PostgreSQL (patrz: http://bit.ly/ZtpbgH). Musisz więc użyć natywnych wyrażeń regularnych PostgreSQL, zobacz tutaj: http://bit.ly/ZtpojU – Matt

+0

To działa. Dziękujemy za dodanie wyjaśnienia dotyczącego '\ y'. Jeśli chodzi o część '{0} 'format (stringVariable)', czy jest to po prostu inny sposób zapisu ''% s '% stringVariable'? Oba wydają się działać dla mnie. – GChorn

1

Możesz być w stanie uzyskać coś przez upuszczenie regex i za pomocą kilku wyszukiwań django

result = Model.objects.filter(Q(text__contains=' someword ') | 
           Q(text__contains=' someword.') | 
           Q(text__istartswith = 'someword.' | 
           Q(text__istartswith = 'someword.' | 
           Q(text__iendswith = 'someword') 

zobaczyć here do dokumentów.

Rozumiem, że nie jest to takie eleganckie (ale ułatwia konserwację, jeśli nie jesteś fanem regex).

+1

Ponieważ to nie powoduje dopasowania całego słowa; na przykład, jeśli robię 'text__contains = 'tart'', wybieram wyniki takie jak' start'. – GChorn

+0

moje złe - nie znam się na sql wystarczająco, by wiedzieć, że "cały mecz" oznacza coś konkretnego. W każdym razie, zaktualizowałem swoją odpowiedź, aby nieco ją poprawić. –

+0

Łatwa konserwacja? Jest wiele przypadków, w których się nie ukrywasz (między '()', przecinkami, itd.). –

0

miałem ten sam problem próbuje dopasować granice słowo, używając Perl kompatybilnego sekwencji escape \ b. Moja baza danych backendu to MySQL.

Rozwiązałem problem za pomocą wyrażenia klasy znaków [[: space:]], np.

 q_sum = Q() 
     search_list = self.form.cleaned_data['search_all'].split(' '); 
     for search_item in search_list: 
      search_regex = r"[[:space:]]%s[[:space:]]" % search_item 
      q_sum |= Q(message__iregex=search_regex) 
     queryset = BlogMessages.objects.filter(q_sum).distinct() 
+0

To nie będzie uwzględniało interpunkcji, tylko dlatego, że wiesz. – yekta

Powiązane problemy