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

#python #regex

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

Вопрос:

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

Я хочу извлечь всю предоставленную информацию из сообщения чата. Итак, у меня есть следующий шаблон $ [BOT] [НЕНУЖНЫЕ ПРОБЕЛЫ] [COMMAND] [НЕНУЖНЫЕ ПРОБЕЛЫ] [НЕОБЯЗАТЕЛЬНЫЕ АРГУМЕНТЫ В ФОРМАТЕ [КЛЮЧ] = [ЗНАЧЕНИЕ], РАЗДЕЛЕННЫЕ НА НЕНУЖНЫЕ ПРОБЕЛЫ]

Например:

  1. $mail-bot[WS]показать
  2. $mail-bot[WS][WS]показать
  3. $mail-bot[WS]показать [WS]
  4. $mail-bot[WS]показать [WS][WS]
  5. $mail-bot[WS]показать [WS] [WS][WS]
  6. $mail-bot[WS]show[WS]a=1
  7. $mail-bot[WS]show[WS][WS]a=1
  8. $mail-bot[WS]показать [WS] [WS][WS]a=1
  9. $mail-bot[WS]show[WS]a=1 [WS] d = 4
  10. $mail-bot[WS]show[WS]ab=43[WS][WS]cd= 23

Объяснение: [WS] обозначает пробел (извините, я не смог отобразить их в предварительном просмотре).

 $mail-bot show
$mail-bot  show
$mail-bot show 
$mail-bot show  
$mail-bot show   
$mail-bot show a=1
$mail-bot show  a=1
$mail-bot show   a=1
$mail-bot show a=1 d=4
$mail-bot show ab=43  cd=23
 

Ожидаемый результат (для всех примеров):
bot=mail-bot
cmd=show

Ожидаемый результат (для 6. до 8.): arguments=[{'a': '1'}]

Ожидаемый результат (для 9.): arguments=[{'a': '1', 'd': '4'}]

Ожидаемый результат (для 10.): arguments=[{'ab': '43', 'cd': '23'}]

Регулярное выражение, которое у меня есть сейчас, выглядит следующим образом: ^$(?<bot>[A-Za-z-_] )(?<ws1> {0,})(?<cmd>[A-Za-z-_] )(?<options>(?<ws2> {1,})(?<argument>(?<ws3> {0,})(?<key>w )=(?<value>w )){0,}){0,1}$

До сих пор я тестировал данное регулярное выражение в regex101, и то, что я могу извлечь, — это вся информация, за исключением аргументов, если их несколько. Таким образом, случаи с 1 по 8 работают с данным регулярным выражением, а с 9 и 10 — нет.

Кто-нибудь может мне помочь с этим? Спасибо!

С наилучшими пожеланиями, mr_5p4rk_

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

1. Пожалуйста, вставьте текст для сканирования

2. Стандартный re модуль Python может сопоставлять повторяющиеся группы (например, ваш ключ и значение), но не может их эффективно фиксировать, потому что каждое последующее совпадение перезаписывает ранее записанный текст. Возможно regex , вы захотите изучить более новый экспериментальный модуль, который, я полагаю, способен обрабатывать повторяющиеся захваты (хотя я не знаю подробностей).

3. Спасибо за ваш совет. Я попробую это сделать. Но в то же время я пошел другим путем, отделив строку от пар ключ-значение и проанализировав каждую часть отдельно

4. Ваше регулярное выражение содержит синтаксическую ошибку.

Ответ №1:

Следующее регулярное выражение соответствует тому, что вы, кажется, хотите:

 ^$(?P<bot>[A-Za-z-_] ) (?P<cmd>[A-Za-z-_] )(?P<options>  (?P<argument>(?P<key>[a-z] )=(?P<value>[0-9] ))) 
 

Чтобы упростить извлечение параметров (при условии, что их два), вы можете использовать следующее регулярное выражение (и при необходимости расширить его до дополнительных параметров):

 ^$(?P<bot>[A-Za-z-_] ) (?P<cmd>[A-Za-z-_] )(?P<options>  (?P<argument>(?P<key>[a-z] )=(?P<value>[0-9] )))(?P<options2>  (?P<argument2>(?P<key2>[a-z] )=(?P<value2>[0-9] )))
 

Вы можете убедиться, что это работает <a rel=»noreferrer noopener nofollow» href=»https://pythex.org/?regex=^$(?P[A-Za-z-_]+) (?P[A-Za-z-_]+)(?P +(?P(?P[a-z]+)=(?P[0-9]+)))+amp;test_string=$mail-bot show ab=43 cd=23amp;ignorecase=0amp;multiline=0amp;dotall=0amp;verbose=0″ rel=»nofollow noreferrer»>здесь.

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

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

1. @mr_5p4rk_: не могли бы вы, пожалуйста, просмотреть ответ и принять / поддержать его, если сочтете его полезным?