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

#python #regex

Вопрос:

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

 tree/bee.horse_2021/moose/loo.se
bee.horse_2021/moose/loo.se
bee.horse_2021/mo.ose/loo.se
 

Путь может быть сколь угодно долгим после moose этого . Иногда первая часть пути, например, tree/ отсутствует, иногда нет. Я хочу захватить tree в первую группу, если она существует, и bee.horse во вторую.

Я придумал это регулярное выражение, но оно не работает:

 path_regex = r'^(?:(.*)/)?([a-zA-Z] .[a-zA-Z] ). 

Что я здесь упускаю?


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

1.Я думаю, что это работает, разве это не ожидаемое? ^(?:(.*)/)?([a-zA-Z] .[a-zA-Z] ). $ regex101.com/r/BD2eiE/1 Если вы не хотите пересекать первую косую черту, вы можете использовать отрицательный класс символов ^(?:([^/] )/)?([a-zA-Z] .[a-zA-Z] ). $

2. Я обновил описание. Регулярное выражение 101, которое вы опубликовали, работает, но если у меня есть компонент пути с точкой, это не так

3.С отрицаемым классом символов это сработало бы тогда? ^(?:([^/n] )/)?([a-zA-Z] .[a-zA-Z] ).*$ regex101.com/r/igeaXN/1

4. извините, не работает для bee.horse_2021/mo.ose/loo.se

5. В этом случае вы также можете исключить совпадение с точкой ^(?:([^/n.] )/)?([a-zA-Z] .[a-zA-Z] ).*$ см. regex101.com/r/MYlT5C/1 Или ограничьте возможные символы для группы 1, чтобы они соответствовали только символам слов ^(?:(w )/)?([a-zA-Z] .[a-zA-Z] ).*$ см. regex101.com/r/DY66LV/1

Ответ №1:

Вы можете ограничить сопоставление символов в первой группе захвата.

Например, вы можете сопоставить любой символ, кроме / или . используя класс отрицаемых символов [^/n.]

 ^(?:([^/n.] )/)?([a-zA-Z] .[a-zA-Z] ).*$
 

Демонстрация регулярных выражений

Или вы можете ограничить символы, чтобы они соответствовали w только символам слов

 ^(?:(w )/)?([a-zA-Z] .[a-zA-Z] ).*$
 

Демонстрация регулярных выражений

Обратите внимание, что в вашем шаблоне . в конце соответствует как минимум одному символу. Если вы хотите сделать эту часть необязательной, вы можете изменить ее на .*

Что я здесь упускаю?

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

1.Я думаю, что это работает, разве это не ожидаемое? ^(?:(.*)/)?([a-zA-Z] .[a-zA-Z] ). $ regex101.com/r/BD2eiE/1 Если вы не хотите пересекать первую косую черту, вы можете использовать отрицательный класс символов ^(?:([^/] )/)?([a-zA-Z] .[a-zA-Z] ). $

2. Я обновил описание. Регулярное выражение 101, которое вы опубликовали, работает, но если у меня есть компонент пути с точкой, это не так

3.С отрицаемым классом символов это сработало бы тогда? ^(?:([^/n] )/)?([a-zA-Z] .[a-zA-Z] ).*$ regex101.com/r/igeaXN/1

4. извините, не работает для bee.horse_2021/mo.ose/loo.se

5. В этом случае вы также можете исключить совпадение с точкой ^(?:([^/n.] )/)?([a-zA-Z] .[a-zA-Z] ).*$ см. regex101.com/r/MYlT5C/1 Или ограничьте возможные символы для группы 1, чтобы они соответствовали только символам слов ^(?:(w )/)?([a-zA-Z] .[a-zA-Z] ).*$ см. regex101.com/r/DY66LV/1

Ответ №1:

Вы можете ограничить сопоставление символов в первой группе захвата.

Например, вы можете сопоставить любой символ, кроме / или . используя класс отрицаемых символов [^/n.]


Демонстрация регулярных выражений

Или вы можете ограничить символы, чтобы они соответствовали w только символам слов


Демонстрация регулярных выражений

Обратите внимание, что в вашем шаблоне . в конце соответствует как минимум одному символу. Если вы хотите сделать эту часть необязательной, вы можете изменить ее на .*