Изменить выборочный символ при помощи регулярных выражений

<span class="_ _179">

я хочу изменить " " на ' ' Написал регулярное выражение

tag = re.sub(r'<span class="_ _\d{1,6}">', r'', str(tag))

что передать вторым параметром (на что меняем)?

я это вижу как то так

tag = re.sub(r'<span class="_ _\d{1,6}">', r'<span class='_ _числокотороенашлось'>', str(tag))

Но как это записать?


Ответы (2 шт):

Автор решения: gil9red

Можно в re.sub передавать функцию, через которую можно сделать замену всего встреченного выражения на новое

Пример:

import re


def on_match(m: re.Match) -> str:
    return f"<span class='{m.group(1)}'>"


text = '''<span class="_ _160">
<span class="_ _150">
<span class="_ _2">'''

new_text = re.sub(r'<span class="(_ _\d{1,6})">', on_match, text)
print()
print(new_text)

Еще можно сделать on_match без составления новой строки, меняя только найденную:

def on_match(m: re.Match) -> str:
    return m.group().replace('"', "'")

Результат:

<span class='_ _160'>
<span class='_ _150'>
<span class='_ _2'>
→ Ссылка
Автор решения: GrAnd

В регулярных выражениях есть возможность ссылаться на уже найденные группы (т.е. подставлять содержимое группы на место ссылки), так называемый backreference (они же обратные ссылки).

You can match a previously captured group later within the same regex using a special metacharacter sequence called a backreference.

\<n>

Matches the contents of a previously captured group.

Within a regex in Python, the sequence \<n>, where <n> is an integer from 1 to 99, matches the contents of the <n>th captured group.

Поэтому вся замена сводится к одной строчке:

tag = re.sub(r'(<span class=)"(_ _\d{1,6})"(>)', r"\1'\2'\3", tag)

Или более универсальный regexp где учитываются возможные пробелы в tag:

tag = re.sub(r'(<\s*span\s+class\s*=\s*)"(_ _\d{1,6})"(\s*>)', r"\1'\2'\3", tag)
→ Ссылка