2013-02-21 20 views
8

Sto tentando di scrivere una query Django che corrisponderà solo a parole intere. Sulla base della risposta here, ho provato qualcosa di simile:Corrispondenza parola intera solo nella query Django

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

Ma questo non restituisce il risultato atteso. Ho anche provato

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

inutilmente. Il mio obiettivo finale è quello di essere in grado di passare in una variabile stringa come bene, qualcosa di simile a:

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

o

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

Ma in questo momento non riesco nemmeno a farlo funzionare con una corda grezzo . Sto usando PostgreSQL.

+0

Che database stai utilizzando? – Matt

+0

@MattStevens, sto usando PostgreSQL. – GChorn

risposta

11

Usa “\ y” invece di “\ b” quando si utilizza PostgreSQL, questo è perché Django passa l'espressione regolare verso il basso a PostgreSQL - quindi bisogno del vostro RegEx per essere compatibile con esso. Dovresti essere in grado di eseguirli da psql senza problemi.

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

See: http://bit.ly/ZtpojU

+1

Che cosa è esattamente '\ y'? –

+0

Django non esegue alcuna conversione di PCRE in espressioni regolari di PostgreSQL (vedere: http://bit.ly/ZtpbgH). Quindi devi solo usare le espressioni regolari native di PostgreSQL, vedi qui: http://bit.ly/ZtpojU – Matt

+0

Questo funziona. Grazie per aver aggiunto anche la spiegazione su '\ y'. Per quanto riguarda la parte '' {0} '. Format (stringVariable) 'è solo un altro modo di scrivere''% s '% stringVariable'? Entrambi sembrano funzionare per me. – GChorn

1

Potreste essere in grado di ottenere qualcosa facendo cadere la regex e utilizzando un paio di ricerche 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') 

vedere here per documenti.

Mi rendo conto che non è così elegante (ma facilita la manutenzione se non sei un appassionato di regex).

+1

Perché questo non esegue una corrispondenza parola intera; per esempio, se faccio un 'text__contains = 'tart'' raccolgo risultati come' start'. – GChorn

+0

my bad - Ovviamente non ho dimestichezza con SQL abbastanza da sapere che "whole word match" significa qualcosa di specifico. Ad ogni modo, ho aggiornato la mia risposta per migliorarla un po '. –

+0

Manutenzione facile? Ci sono molti casi che non stai coprendo lì (tra '()', virgole, ecc. –

0

ho avuto lo stesso problema cercando di abbinare i confini di parola utilizzando il compatibile con Perl sequenza di escape \ b. Il mio database di back-end è MySQL.

Ho risolto il problema con l'espressione della classe di carattere [[: space:]], ad es.

 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

Questo non terrà conto della punteggiatura solo per quello che sai. – yekta

Problemi correlati