Разделение строки на динамический разделитель - PullRequest
0 голосов
/ 31 октября 2018

Я должен решить следующую проблему. Я должен извлечь сообщения из буфера связи. К сожалению, протокол связи является паршивым и плохо структурированным. Единственный способ, которым я придумал различать пакеты в буфере, - это промежуточная команда «ack», которая передается сервером.

Пример:

[Packet1] [ACK] [Packet2] [ACK] [Packet3]

Я мог бы использовать String.Split (ACK), но разделитель также не согласован. Тем не менее, есть 3 правила для идентификации ack-пакета.

  1. Начинается с "АК".
  2. Заканчивается на "0" или "1".
  3. Общая длина 5 символов.

Пример подтверждения:
"AKxxy" где:
хх: (от 01 до 99)
y: (0 или 1)

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

Есть ли в RegEx "эксперт", который может мне помочь? Не стесняйтесь предложить любое решение.
Спасибо.

Edit:
Пример пакета (мне действительно пришлось удалить информацию о пакете):
AK010CONFIDENTIALPACKET1AK011CONFIDENTIALPACKET2AK020AK011CONFIDENTIALPACKET3AK021CONFIDENTIALPACKET4AK050

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

Ответы [ 3 ]

0 голосов
/ 31 октября 2018
string interim = Regex.Replace(buffer, "AK\d{2}[01]", "|");
var commands = interim.Split('|');

Предполагая, что | не является допустимым символом ввода. Вы можете выбрать что-нибудь очень экзотическое.

0 голосов
/ 31 октября 2018

EDIT:

Глядя на другие ответы, это, вероятно, просто декоративная ценность. Решение @Jan и @ ThymosK

var packets = Regex.Split(buffer, @"AK\d{2}[01]");

кажется гораздо более элегантным.

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

Я разработал регулярное выражение, которое может давать вам сообщения и разделители в виде групп:

(?s)(AK[0-9][0-9][0,1])|((?:(?!AK[0-9][0-9][0,1]).)*)

Он может анализировать текст следующим образом: enter image description here

Вы можете проверить это здесь .

Как обычно, регулярные выражения только для записи. Я вряд ли могу прочитать это сам. Но я постараюсь пройти через это:

Первая группа проста и просто ловит вашу команду подтверждения:

(AK[0-9][0-9][0,1])

Вторая группа содержит отрицательный прогноз (?! ... ), который соответствует чему-либо, за чем не следует регулярное выражение, заданное .... Здесь мы вставляем ваш синтаксис ack, поэтому все, за чем не следует ack, сопоставляется. Затем мы добавляем один символ, чтобы расширить его, чтобы он соответствовал чему угодно до ack. По сути, эта вторая часть утверждает, что в настоящее время мы не следуем ack, а затем добавляем один символ. Это повторяется как можно дольше, пока мы не найдем ack. Я превращаю это во вторую группу.

Поскольку в настоящее время у меня нет C #, я не могу обернуть это в код с помощью движка C # regex. Но python прекрасно работает с ним и предлагает полезный метод findall, который дает вам все эти группы.

0 голосов
/ 31 октября 2018

Прямой перевод будет

\bAK\d{2}[01]\b

То есть

\b    # a word boundary
AK    # AK literally
\d{2} # two digits
[01]  # one of 0 or 1
\b    # another word boundary

Хотя выражение необходимо проверить (см. демонстрацию на regex101.com ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...