Как я уже сказал в комментариях, поиски не перекрываются, следующий найденный находится в оставшейся части.
Что вы можете сделать идея # 1 :
re.sub
каждое ключевое слово отдельно в al oop.
Конечно, если поиски перекрываются, вы можете иметь некоторые <em>
или </em>
, которые уже находятся на пути - как здесь, ame
не будет совпадать с am</em>e
- поэтому вам нужно изменить регулярные выражения с одним ключевым словом. Включите (?:</?em>)?
между буквами.
terms = re.findall('[a-z0-9]+', query_term, re.I)
terms.sort(key=len, reverse=True)
replace_content = content
for term in terms:
term_regex = "(?:</?em>)?".join(term)
replace_content = re.sub(rf"({term_regex})", r'<em>\1</em>', replace_content, flags = re.I)
print(replace_content)
Результаты для обоих случаев:
<em>s<em>t</em><em>a</em>g</em>ing_da<em>ta</em><em>st</em>or<em>ag</em>e
<em>g<em>am</em>e</em>_event
Идея # 2
Вы можете предварительно обработать сами ключевые слова, найти, какие префиксы соответствуют суффиксам, и объединить их с другими ключевыми словами.
Здесь: gam
имеет суффикс am
, ame
имеет префикс am
- > вы добавляете game
к вашим условиям.
Эта идея даст этот "идеальный результат"
Идея № 3 *
Сделайте идею № 1, удалите вложенные блики и объедините те, которые находятся рядом друг с другом (ie удалить </em><em>
).
Эта идея даст этот "идеальный результат" "также.
Чтобы удалить один уровень вложенности, выполните:
re.sub(r"<em>([^/]*)<em>([^/]*)</em>([^/]*)</em>", r"<em>\1\2\3</em>", replace_content, flags = re.I)
Регулярное выражение работает, находя теги в порядке <em>
<em>
</em>
</em>
(вложенный) с любыми группами символов без /
между ними (быстрый способ убедиться, что мы берем только ближайший закрывающий тег).
Очевидно, только с одним уровнем вложенности Если удалить, нам нужно использовать это также в al oop - это будет while
l oop: хотя замены отличаются от прошлых раз, замена снова = останавливается, когда замена больше не вносит изменений.
final_result = ""
while final_result != replace_content:
final_result = replace_content
replace_content = re.sub(r"<em>([^/]*)<em>([^/]*)</em>([^/]*)</em>", r"<em>\1\2\3</em>", final_result, flags = re.I)
print(final_result)
В случае Case2 требуется только одна замена, поэтому давайте посмотрим, как она работает с case1:
<em>stag</em>ing_da<em>ta</em><em>st</em>or<em>ag</em>e
Теперь для этого нужно только удалить </em><em>
, как я уже говорил!
Окончательный фрагмент кода, который нужно поставить после кода идеи № 1:
final_result = ""
while final_result != replace_content:
final_result = replace_content
replace_content = re.sub(r"<em>([^/]*)<em>([^/]*)</em>([^/]*)</em>", r"<em>\1\2\3</em>", final_result, flags = re.I)
final_result = final_result.replace("</em><em>", "")
print(final_result)
Дает:
<em>stag</em>ing_da<em>tast</em>or<em>ag</em>e