У меня есть длинная строка, которая может состоять из нескольких подстрок (не всегда, иногда это одна строка, иногда 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
Как я могу заставить его работать??
Если первые два символа кодируют длину строки в шестнадцатеричном формате, почему вы не используете это, чтобы решить, какую часть строки использовать? Однако смещения в вашем примере кажутся неправильными; 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
Но что, если у меня есть другие строки, но с 7E, 6E, BE и т. д. Я просто добавляю значения в код? Я имею в виду, что я бы хотел иметь "универсальный" разветвитель, какой бы длины он ни был, он должен разветвляться. Так что иногда здесь 7E, 6E, BE, 4E или 4D в начале, и ID тоже может быть другим, например, у меня может быть 44B909, но у меня может быть 44B606 (44 здесь всегда)
Мы можем решить только те проблемы, о которых вы действительно спрашиваете. Обновить регулярное выражение несложно, но, конечно, если значения могут быть любыми, вы не можете ожидать, что они также не будут случайным образом встречаться внутри данных. [467B][DE](?=44B) будет работать для перечисленных вами случаев, но что-то более общее, чем это, вероятно, будет иметь ложные срабатывания.
Возможно, см. также страницу с информацией о теге регулярного выражения Stack Overflow для некоторых ресурсов для начинающих и обучающих ссылок.
Почему он иногда удаляет первые 2 буквы? Например, он начинается с «4D44B409626», но выводит «44B409626».
Он разбивается на два совпадения и отбрасывает их. Вы также можете переместить их в просмотр вперед (поместить их после (?=), если хотите сохранить их. Опять же, ваш вопрос, похоже, просил их удалить.
Извините, тогда я мог ошибиться... Я просто хотел разделить строки, ничего не удаляя
Кстати, можно ли одновременно искать несколько ID? Я имею в виду что-то вроде «[467B][DE](?=44B)(?=44E) ?
Я думаю, вы имеете в виду (?=44[BE])
Я хочу подчеркнуть, что вы можете выучить достаточное количество регулярных выражений, чтобы решить вашу насущную проблему примерно за 15 минут, и, к сожалению, достаточно, чтобы начать отвечать на регулярные выражения вопросы на этом сайте примерно через день. Если после этого вам все еще нужна помощь, возможно, задайте новый вопрос, сосредоточив внимание на четко определенной проблеме, которую вы не можете понять из базовой документации.
Я тоже пробовал это с len = int(string[:2], 16)*2, но похоже, что он "случайно" разделил эти строки