Как заменить числа в строке числами из другого списка? - PullRequest
0 голосов
/ 20 октября 2019

У меня есть текстовая строка, которая содержит числа. Плюс, у меня есть список номеров. Я хочу заменить числа в строке числами из списка в порядке следования строки и списка.

Используя Regex, я извлек из строки существующие числа, а также передал их в список итеперь у меня есть соответствие между исходным номером и альтернативным номером. Тем не менее, до сих пор неясно, как я могу находить корректировки и вносить замены по порядку.

с помощью этой строки я извлекаю числа из данной строки:

    list_of_numbers_in_string = [int(x) for x in re.findall('\d+', str)]

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

    data = 'readingOrder {index:24;} person {offset:0; length:7;} textStyle {offset:0; length:7; underlined:true;} place {offset:52; length:8;} textStyle {offset:52; length:8; underlined:true;}'
    new_numbers = [24, 0, 12, 0, 12, 58, 14, 58, 14]

получить этот вывод:

    corrected_data = 'readingOrder {index:24;} person {offset:0; length:12;} textStyle {offset:0; length:12; underlined:true;} place {offset:58; length:14;} textStyle {offset:58; length:14; underlined:true;}'

Ответы [ 3 ]

1 голос
/ 20 октября 2019

Принятый ответ на самом деле неверен (теперь он удален). data.replace() заменит первое вхождение числа, которое не всегда является правильным. Например, когда вы пытаетесь заменить 8 на 14, он фактически заменяет 58 на 514.

Вот мое решение:

import re

data = 'readingOrder {index:24;} person {offset:0; length:7;} textStyle {offset:0; length:7; underlined:true;} place {offset:52; length:8;} textStyle {offset:52; length:8; underlined:true;}'
new_numbers = [24, 0, 12, 0, 12, 58, 14, 58, 14]

offset = 0
for index, match in enumerate(re.finditer('\d+', data)):
    data = data[:match.start() + offset] + str(new_numbers[index]) + data[match.end() + offset:]
    offset += len(str(new_numbers[index])) - match.end() + match.start()
0 голосов
/ 21 октября 2019

альтернатива

import re

data = 'readingOrder {index:24;} person {offset:0; length:7;} textStyle {offset:0; length:7; underlined:true;} place {offset:52; length:8;} textStyle {offset:52; length:8; underlined:true;}'
new_numbers = [24, 0, 12, 0, 12, 58, 14, 58, 14]
x = re.findall("\d+", data)
data = data.replace("{","{{").replace("}","}}")
for n in x:
    data = data.replace(n,"{}",1)
data = data.format(*new_numbers)
print(data)

[Out]:

readOrder {index: 24;} person {offset: 0;длина: 12;} textStyle {смещение: 0;Длина: 12;подчеркнуто: true;} place {offset: 58;длина: 14;} textStyle {смещение: 58;Длина: 14;подчеркнуто: true;}

0 голосов
/ 20 октября 2019

Если вы работаете непосредственно с data (как string) с одним new number за раз (т. Е. in a for loop вы делаете data = operate on data), то, вероятно, сложность времени будет O(len(new_numbers) * len(data)).

Один эффективный способ сделать это за O(len(data)) время - это оперировать a list of characters:

def replace_numbers(data, new_numbers):
    new_numbers_idx = 0
    data_as_char_list = []

    skip = False

    for data_ch in data:
        if data_ch.isdigit():
            if not skip:
                # When we encounter any number's first digit in data, we will add the new number, and in the next iterations we will skip rest of the digits in data.
                # e.g. data = 'hi123hi', new_numbers = [444], then when we encounter `1` we will add ['4', '4', '4'] and skip the rest of the digits '2' and '3' from data by setting skip = True.
                new_number_as_char_list = list(str(new_numbers[new_numbers_idx]))
                data_as_char_list.extend(new_number_as_char_list)
                new_numbers_idx += 1
                skip = True
        else:
            data_as_char_list.append(data_ch)
            skip = False

    return ''.join(data_as_char_list)


data = 'readingOrder {index:24;} person {offset:0; length:7;} textStyle {offset:0; length:7; underlined:true;} place {offset:52; length:8;} textStyle {offset:52; length:8; underlined:true;}'
new_numbers = [24, 0, 12, 0, 12, 58, 14, 58, 14]
data = replace_numbers(data, new_numbers)

corrected_data = 'readingOrder {index:24;} person {offset:0; length:12;} textStyle {offset:0; length:12; underlined:true;} place {offset:58; length:14;} textStyle {offset:58; length:14; underlined:true;}'
assert data == corrected_data
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...