Регулярное выражение для сопоставления только законных токенов и удаления символов при первом признаке плохого токена

#python #regex

#python #регулярное выражение

Вопрос:

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

 (?x)
^(?:[^S]*)
(?:S
    (?:
        (?:(PING|PONG)E)                  # match and capture a token
        |
        (?!P).                            # match and discard all that don't start with any prefix of the tokens
        |
        . (?<!PING|PONG|PIN|PON|PI|PO|P)$ # match and discard all that don't end properly (if there's garbage at the end)
    )
)?
 

Демонстрация этого регулярного выражения здесь: https://regex101.com/r/IGCnLE/4

Я пытаюсь поэкспериментировать с регулярным выражением как простым лексером. В основном есть поток символов с сообщениями типа SPINGE и SPONGE . Но в нем могут быть и другие вещи. Я использую приведенное выше регулярное выражение для выполнения 2 вещей. Один, чтобы найти все символы, которые следует отбросить, поскольку они не могут привести к законному захвату, и два, чтобы захватить первый законный токен, который появляется.

Приведенное выше регулярное выражение работает во всех случаях, кроме этих 2:

 SPINGP
SPINGPINPINGPING
 

Приведенные выше 2 являются частично полностью сообщениями без конечного фрейма E . Но поскольку у них есть некоторый мусор после PING , это означает, что это не законные токены для захвата. Вся строка должна быть сопоставлена и отброшена. Но я не могу понять это.

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

Другие тестовые примеры находятся на веб-сайте: https://regex101.com/r/IGCnLE/4 и скопировано здесь:

 S
SP
SPI
SPIN
SPING
SPONG
SPO
SPINGP
SPINGPINPINGPING
SPINGESPONGE
abcSPINGEabc
SPINGEabc
abcS
abcS   
Sabc...
SP   
SPINGG

S   
abc
SPONGe
SOP
SNIPO
SabcPINGE
SPINGabcE
SabcE
 

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

Комментарии:

1. Почему бы просто не сопоставить SP[IO]NGE ?

2. @melpomene Потому что мне все еще нужно отбрасывать бесполезные символы из моего потока символов. Если бы это было так просто, я бы не задавал этот вопрос.

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

4. @CMCDragonkai Звучит так, как будто вы можете создать FSM для соответствия SP[IO]NGE , если проблема в том, что вы хотите передавать ему данные постепенно.

5. @melpomene lexical_analysis = re.search(protocol, client_input_buffer.decode('ascii')) тогда token = lexical_analysis.group(1) тогда client_input_buffer = client_input_buffer[lexical_analysis.span()[1]:] . Независимо token от того, является ли это None или нет, запрашивает операцию обработки токена. Это span() позволяет мне использовать индекс сопоставления регулярных выражений для удаления данных. Весь код написан на Python.