gedev
@gedev
сисадмин-энтузиаст

Как заменить произвольное количество вхождений подстроки в строке?

Скрипт на Python 3 читает файл построчно, обрабатывает строки и записывает результат также построчно в новый файл.

import re

input_file = open('in.txt', 'r')
output_file = open('out.txt', 'w')

pattern = re.compile(r'#\w{6}')

for line in input_file:
    colors = pattern.findall(line)
    if not colors:
        output_file.write(line)
    else:
        for color in colors:
            inverted_color = '#'+str(color)[1:7].upper()
            new_line = line.replace(color, inverted_color)
        output_file.write(new_line)

input_file.close()
output_file.close()


Пример входных данных (in.txt):

This is line #aabbcc #ddeeff

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

Сложность заключается в том, что строка это неизменяемый тип данных и в результате выполнения данного скрипта я вместо:

This is line #AABBCC #DDEEFF

Получаю:

This is line #aabbcc #DDEEFF

Как в этом случае использовать списки или кортежи я придумать не смог.

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

Функцию re.sub() я использовать не могу, так как тогда получется, что все вхождения в строке заменяются на одинаковые.
Например, если в строке три цвета: #aaaaaa #bbbbbb #cccccc, то в результате будет: #AAAAA #AAAAAA #AAAAAA.
  • Вопрос задан
  • 53 просмотра
Решения вопроса 1
Можно решит тупо в лоб. не сильно напрягаясь, а можно заморочатся и найти более элегантное и быстрое решение.
Мне в лом думать, поэтому вот решение в лоб
import re

input_file = """This is line #aabbcc #ddeeff
This is line #aab66c #ddee44
This is line #aabbcc #cceeff #aa11cc #dd22ff
This is line #aabbcc #ddee00 #dd11ff"""

pattern = re.compile(r'#\w{6}')


def invert(color_to_convert):
    table = "".maketrans('0123456789abcdef', 'fedcba9876543210')
    return color_to_convert.lower().translate(table).upper()


def replace(s: str):
    colors = [invert(color) for color in pattern.findall(s)]
    s = pattern.sub("{}", s)
    return s.format(*colors)


for line in input_file.split('\n'):
    print(replace(line))


This is line #554433 #221100
This is line #554993 #2211BB
This is line #554433 #331100 #55EE33 #22DD00
This is line #554433 #2211FF #22EE00
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы