Python необязательная группа в регулярном выражении - PullRequest
0 голосов
/ 20 июня 2020

У меня есть следующее регулярное выражение в Python:

m = re.match(r'(?P<name>[a-zA-Z0-9]+)(?P<limit>_\d+K)(?P<code>_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?.(?P<file_format>\w+)?',
                    file_name, re.M | re.I)

Оно используется для проверки имени файла по заданному шаблону c, и я также беру значения групп из файла имя так:

name = m.group ('name')

Это отлично работает, если имя файла точно в заданном формате, например:

file_name = "name_122K_someCode_someotherthing.jpg"

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

Как мне сделать группы и optional, чтобы шаблон совпадал даже если какой-либо из них или оба отсутствуют в имени файла?

1 Ответ

2 голосов
/ 20 июня 2020

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

Поскольку пробелов нет, вы можете добавить к шаблону положительный знак lookahead ^(?=\S+\.\w+$), чтобы подтвердить хотя бы один символ без пробелов, соответствующий группе file_format.

Примечание, чтобы избежать точки \., чтобы соответствовать ей буквально

^(?=\S+\.\w+$)(?P<name>[a-zA-Z0-9]+)?(?P<limit>_\d+K)?(?P<code>_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?\.(?P<file_format>\w+)$

Regex demo

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

^(?=\w)(?P<name>[a-zA-Z0-9]+)?(?P<limit>_\d+K)?(?P<code>_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(_[a-zA-Z0-9]+)?(?:\.(?P<file_format>\w+))?$

Regex demo

Edit В соответствии с предложением @ JvdV , вы можете немного сократить шаблон, используя квантификатор для захвата всех значений дополнительных групп захвата в одну группу:

^(?=\w)(?P<name>[a-zA-Z0-9]+)?(?P<limit>_\d+K)?(?P<code>_[a-zA-Z0-9]+)?((?:_[a-zA-Z0-9]+){0,4})(?:\.(?P<file_format>\w+))?$

Regex demo

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