Так вы пытаетесь выделить выделено жирным шрифтом в виде набора ключевых слов. Сейчас этот код нарушен довольно многими способами. Вы используете модуль 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)
Все это делает преобразование символов, как <
в <
которого браузер будет показывать, как <
, но не будет интерпретироваться как начало тега.Поэтому, если плохой парень набирает <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
Я призываю вас потратить время, чтобы понять, что это делает, иначе вы просто будете ввязываться в беспорядок! Всегда проще просто вырезать и вставлять и двигаться дальше, но это приводит к дерьмовому сломанному коду и хуже всего означает, что вы сами не улучшаетесь и не учитесь. Все отличные кодеры начинаются как начинающие кодеры, которые нашли время, чтобы понять вещи :)
Hi Aidan, что вы пытаетесь сделать с этим кодом? Похоже, что с ошибкой есть несколько ошибок. –
Ошибка, которую вы получаете прямо сейчас, вызвана тем фактом, что re.sub выполняет подстановки групп регулярных выражений и что-то в словах, которые вы передаете, ошибочно принимается за ссылки на те группы (которых не существует). Эта проблема с ответами не очень помогает вам, хотя я, вероятно, могу дать вам гораздо более полезный ответ, как только я знаю, что вы намеревались сделать для кода :) –
Привет, на самом деле это задано мной. Этот код в основном извлекает часть q ['display'] (то есть type = 1), и несколько ключевых слов (выполняемых в regex) искали по этому qitem ['value'] (который является строкой) и выделите слово как BOLD, если оно найдено с помощью регулярного выражения. – jdtoh