2013-03-03 2 views
0

Я столкнулся с ошибкой «плохое имя группы».Django: Плохая группа имя

Вот код:

for qitem in q['display']: 
    if qitem['type'] == 1: 
     for keyword in keywordTags.split('|'): 
      p = re.compile('^' + keyword + '$') 
      newstring='' 
      for word in qitem['value'].split(): 
       if word[-1:] == ',': 
        word = word[0:len(word)-1] 
        newstring += (p.sub('<b>'+word+'</b>', word) + ', ') 
       else: 
        newstring += (p.sub('<b>'+word+'</b>', word) + ' ') 
      qitem['value']=newstring 

А вот ошибка:

error at /result/1/ bad group name Request Method: GET Django Version: 1.4.1 Exception Type: error Exception Value: bad group name Exception Location: C:\Python27\lib\re.py in _compile_repl, line 257 Python Executable: C:\Python27\python.exe Python Version: 2.7.3 Python Path: ['D:\ExamPapers', 'C:\Windows\SYSTEM32\python27.zip', 'C:\Python27\DLLs', 'C:\Python27\lib', 'C:\Python27\lib\plat-win', 'C:\Python27\lib\lib-tk', 'C:\Python27', 'C:\Python27\lib\site-packages'] Server time: Sun,3 Mar 2013 15:31:05 +0800

Traceback Switch to copy-and-paste view

C:\Python27\lib\site-packages\django\core\handlers\base.py in get_response response = callback(request, *callback_args, **callback_kwargs) ... ▶ Local vars ? D:\ExamPapers\views.py in result newstring += (p.sub(''+word+'', word) + ' ') ... ▶ Local vars

Таким образом, ошибка в:

newstring += (p.sub('<b>'+word+'</b>', word) + ' ') 
+0

Hi Aidan, что вы пытаетесь сделать с этим кодом? Похоже, что с ошибкой есть несколько ошибок. –

+0

Ошибка, которую вы получаете прямо сейчас, вызвана тем фактом, что re.sub выполняет подстановки групп регулярных выражений и что-то в словах, которые вы передаете, ошибочно принимается за ссылки на те группы (которых не существует). Эта проблема с ответами не очень помогает вам, хотя я, вероятно, могу дать вам гораздо более полезный ответ, как только я знаю, что вы намеревались сделать для кода :) –

+0

Привет, на самом деле это задано мной. Этот код в основном извлекает часть q ['display'] (то есть type = 1), и несколько ключевых слов (выполняемых в regex) искали по этому qitem ['value'] (который является строкой) и выделите слово как BOLD, если оно найдено с помощью регулярного выражения. – jdtoh

ответ

1

Так вы пытаетесь выделить выделено жирным шрифтом в виде набора ключевых слов. Сейчас этот код нарушен довольно многими способами. Вы используете модуль re прямо сейчас, чтобы соответствовать ключевым словам, но вы также разбиваете ключевые слова и строки вниз на отдельные слова, вам не нужно делать то и другое, и взаимодействие между этими двумя разными подходами к решению проблемы что вызывает у вас проблемы.

Вы можете использовать регулярные выражения для одновременного сопоставления нескольких возможных строк, для чего они подходят! Поэтому вместо "^keyword$" для соответствия только «ключевому слову» вы можете использовать "^keyword|hello$" для соответствия либо «keyword», либо «hello». Вы также используете символы ^ и $, которые соответствуют только началу или концу всей строки, но то, что вы, вероятно, хотели первоначально, должно было соответствовать началу или концу слов, для этого вы можете использовать \b вот так: r"\b(keyword|hello)\b". Обратите внимание, что в последнем примере я добавил перед строкой символ , это означает «raw» и отключает питоны, обычно обрабатывая символы обратной косой черты, которые конфликтуют с регулярными выражениями, это хорошая практика: всегда использовать r перед строкой когда строка содержит регулярное выражение. Я также использовал скобки для группировки слов.

Метод регулярного выражения sub позволяет вам подставлять элементы, соответствующие регулярному выражению, другой строкой. Он также позволяет вам делать «обратные ссылки» в заменяющей строке, содержащей части исходной строки, которые соответствуют друг другу. Части, которые он включает, называются «группами» и обозначаются скобками в исходном регулярном выражении, в приведенном выше примере имеется только один набор скобок, и они являются первыми, поэтому они обозначены обратным ссылкой \1. Причина фактического сообщения об ошибке, о котором вы спрашивали, заключается в том, что ваша строка замены содержала то, что выглядело как backref, но в вашем регулярном выражении не было никаких групп.

Используя, что вы делаете что-то вроде этого:

keywordMatcher = re.compile(r"\b(keyword|hello)\b") 
value = keywordMatcher.sub(r"<b>\1</b>", value) 

Другое дело, что не имеет прямого отношения к тому, что вы просите, но это невероятно важно, что вы принимаете исходные текстовые строки (я предполагаю) и превращая их в HTML, это дает много шансов для уязвимостей инъекций скриптов, которые, если вы не нашли времени, чтобы понять и избежать, позволят плохим парням взломать созданные вами приложения (они могут сделать это автоматическим способом, поэтому даже если вы считаете, что ваше приложение будет слишком маленьким, чтобы кто-нибудь заметил, что его все равно можно взломать и использовать для всякого рода плохих вещей, не позволяйте этому случиться!). Основное правило заключается в том, что это нормально, чтобы преобразовать текст в HTML, но вам нужно «бежать» это первое, это очень просто:

from django.utils import html 
html_safe = html.escape(my_text) 

Все это делает преобразование символов, как < в &lt; которого браузер будет показывать, как <, но не будет интерпретироваться как начало тега.Поэтому, если плохой парень набирает <script> в одну из ваших форм, и он обрабатывается вашим кодом, он отображает его как <script> и не выполняет его как скрипт.

Аналогичным образом, если вы используете текст в регулярном выражении, в котором вы не собираетесь использовать специальные символы регулярного выражения, тогда вы также должны избежать этого! Вы можете сделать это с помощью re.escape:

import re 
my_regexp = re.compile(r"\b%s\b" % (re.escape(my_word),)) 

Итак, теперь мы получили, что из пути здесь является метод, который вы можете использовать, чтобы делать то, что вы хотите:

value = "this is my super duper testing thingy" 
keywords = "super|my|test" 

from django.utils import html 
import re 
# first we must split up the keywords 
keywords = keywords.split("|") 
# Next we must make each keyword safe for use in a regular expression, 
# this is similar to the HTML escaping we discussed above but not to 
# be confused with it. 
keywords = [re.escape(k) for k in keywords] 
# Now we reform the keywordTags string, but this time we know each keyword is regexp-safe 
keywords = "|".join(keywords) 
# Finally we create a regular expression that matches *any* of the keywords 
keywordMatcher = re.compile(r'\b(%s)\b' % (keywords,)) 
# We are going to make the value into HTML (by adding <b> tags) so must first escape it 
value = html.escape(value) 
# We can then apply the regular expression to the value. We use a "back reference" `\0` to say 
# that each keyword found should be replace with itself wrapped in a <b> tag 
value = keywordMatcher.sub(r"<b>\1</b>", value) 

print value 

Я призываю вас потратить время, чтобы понять, что это делает, иначе вы просто будете ввязываться в беспорядок! Всегда проще просто вырезать и вставлять и двигаться дальше, но это приводит к дерьмовому сломанному коду и хуже всего означает, что вы сами не улучшаетесь и не учитесь. Все отличные кодеры начинаются как начинающие кодеры, которые нашли время, чтобы понять вещи :)

+0

приятно! оно работает! однако могу ли я спросить, есть ли у вас двухъядерный тег, как мы тоже смели? Например: keywords = "super | my | test thingy" – jdtoh

+0

Это должно действительно хорошо работать с кодом как есть. Регулярное выражение требует, чтобы ключевое слово начиналось и заканчивалось на границе слова, но ничего не говорит о том, что в ключевом слове нет границ слов. Попробуй! –

+0

ОК, извините, я думаю, что сейчас я пробовал, и это не сработало из-за «test thingy». Я должен использовать "test thingy" – jdtoh