Разделить строку по специальному шаблону

У меня есть длинная строка, которая может состоять из нескольких подстрок (не всегда, иногда это одна строка, иногда 4 подстроки склеены). Каждый начинается с длины в байтах, например, 4D или 4E. Ниже приведен пример большой строки, состоящей из 4 подстрок:

4D44B9096268182113077A95C84005D55FCD9D79476DDA4346C7EF1F4F07D4B46693F51812C8B74E4E44B9097368182113077A340040058D55E7E8D3924C57182F6E07A4D3617E100D1652169668636CB54E44B9096868182113077A37004005705FE9461E85F69A4C8E1B00CE03E6337B8F3D853A51C447B9694E44B9096668182113077AA400400555C9FAADA21F1EC93DBD5B579E4E07DDAF75A45D095E72010DBB

После разделения по шаблону вывод ДОЛЖЕН БЫТЬ:

4D44B9096268182113077A95C84005D55FCD9D79476DDA4346C7EF1F4F07D4B46693F51812C8B74E
4E44B9097368182113077A340040058D55E7E8D3924C57182F6E07A4D3617E100D1652169668636CB5
4E44B9096868182113077A37004005705FE9461E85F69A4C8E1B00CE03E6337B8F3D853A51C447B969
4E44B9096668182113077AA400400555C9FAADA21F1EC93DBD5B579E4E07DDAF75A45D095E72010DBB

Каждая длинная строка имеет идентификатор - в данном случае это 44B909, каждая строка имеет этот идентификатор после байтов. Мой исходный код взял первые 6 букв (4D44B9) и разделил строку на это. Это работает в 95% случаев, когда КАЖДАЯ линия имеет одинаковую длину, например 4D. Проблема в том, что не всегда каждая строка имеет одинаковую длину - как в строке выше. Посмотрите на мой код ниже:

def repeat():
    string = input('Please paste string below:'+'\n')
    code = string[:6]   

    print('\n')
    print('SPLITTED:')
    string = string.replace(code, '\n'+'\n'+code)
    
    print(string)


while True:
   repeat()

Когда вы пытаетесь вставить эту одну длинную строку, она не разделит ее, потому что первая строка имеет 4D, а остальные - 4E. Я хотел бы, чтобы он «игнорировал» (на мгновение) первые 2 буквы (4E) и брал шесть следующих букв как «разделенный шаблон»? Вывод должен быть таким, как эти 4 строки выше! Я немного изменил код, но получил странные результаты, как показано ниже:

44B9096268182113077A95C84005D55FCD9D79476DDA4346C7EF1F4F07D4B46693F51812C8B74E
44B9097368182113077A340040058D55E7E8D3924C57182F6E07A4D3617E100D1652169668636CB54E
44B9096868182113077A37004005705FE9461E85F69A4C8E1B00CE03E6337B8F3D853A51C447B9694E
44B9096668182113077AA400400555C9FAADA21F1EC93DBD5B579E4E07DDAF75A45D095E72010DBB

Как я могу заставить его работать??

Я тоже пробовал это с len = int(string[:2], 16)*2, но похоже, что он "случайно" разделил эти строки

michalb93 13.02.2023 11:24
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
Потяните за рычаг выброса энергососущих проектов
Потяните за рычаг выброса энергососущих проектов
На этой неделе моя команда отменила проект, над которым я работал. Неделя усилий пошла насмарку.
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
1
1
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если первые два символа кодируют длину строки в шестнадцатеричном формате, почему вы не используете это, чтобы решить, какую часть строки использовать? Однако смещения в вашем примере кажутся неправильными; 4D правильно (десятичное число 78), но 4E, по-видимому, должно быть 51 (строка на четыре символа длиннее).

Для вопроса о том, как разбивать по слегка изменяющемуся шаблону, регулярное выражение кажется хорошим решением.

import re

splitted = re.split(r'4[DE](?=44B909)', string)

Другими словами, это говорит: «Используйте 4D или 4E в качестве разделителя для разделения, но только если за ним сразу следует 44B909».

(Перед первым значением будет пустая группа, но ее легко убрать или изменить регулярное выражение на r'(?<!^)4[DE](?=44B909O)'.)

Если вы не хотите ничего отбрасывать, включите все в предварительный просмотр:

splitted = re.split(r'(?<!^)(?=4[DE]44B909)', string)

Извините, неуклюжая копия/вставка; конечно должно быть re.split

tripleee 13.02.2023 14:12

Но что, если у меня есть другие строки, но с 7E, 6E, BE и т. д. Я просто добавляю значения в код? Я имею в виду, что я бы хотел иметь "универсальный" разветвитель, какой бы длины он ни был, он должен разветвляться. Так что иногда здесь 7E, 6E, BE, 4E или 4D в начале, и ID тоже может быть другим, например, у меня может быть 44B909, но у меня может быть 44B606 (44 здесь всегда)

michalb93 13.02.2023 14:18

Мы можем решить только те проблемы, о которых вы действительно спрашиваете. Обновить регулярное выражение несложно, но, конечно, если значения могут быть любыми, вы не можете ожидать, что они также не будут случайным образом встречаться внутри данных. [467B][DE](?=44B) будет работать для перечисленных вами случаев, но что-то более общее, чем это, вероятно, будет иметь ложные срабатывания.

tripleee 13.02.2023 14:21

Возможно, см. также страницу с информацией о теге регулярного выражения Stack Overflow для некоторых ресурсов для начинающих и обучающих ссылок.

tripleee 13.02.2023 14:22

Почему он иногда удаляет первые 2 буквы? Например, он начинается с «4D44B409626», но выводит «44B409626».

michalb93 13.02.2023 18:54

Он разбивается на два совпадения и отбрасывает их. Вы также можете переместить их в просмотр вперед (поместить их после (?=), если хотите сохранить их. Опять же, ваш вопрос, похоже, просил их удалить.

tripleee 13.02.2023 19:37

Извините, тогда я мог ошибиться... Я просто хотел разделить строки, ничего не удаляя

michalb93 13.02.2023 19:56

Кстати, можно ли одновременно искать несколько ID? Я имею в виду что-то вроде «[467B][DE](?=44B)(?=44E) ?

michalb93 13.02.2023 20:38

Я думаю, вы имеете в виду (?=44[BE])

tripleee 14.02.2023 06:34

Я хочу подчеркнуть, что вы можете выучить достаточное количество регулярных выражений, чтобы решить вашу насущную проблему примерно за 15 минут, и, к сожалению, достаточно, чтобы начать отвечать на регулярные выражения вопросы на этом сайте примерно через день. Если после этого вам все еще нужна помощь, возможно, задайте новый вопрос, сосредоточив внимание на четко определенной проблеме, которую вы не можете понять из базовой документации.

tripleee 14.02.2023 07:56

Другие вопросы по теме