Перекрывающиеся скобки / скобки при сопоставлении нескольких необязательных групп регулярных выражений - PullRequest
0 голосов
/ 15 апреля 2019

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

Некоторые шаблоны, которые я хотел бы сопоставить:

e.g1: /s0me/p@th/2/json

e.g2: /path

Пока у меня есть это:

(^\/[^/]*)(\/[^/]*)?

Что соответствует только до:

/s0me/p@th

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

(^\/[^/]*)[(\/[^/]*)?]*

ОШИБКА: несоответствующая закрывающая скобка

Я использую https://www.regextester.com дляэто.

Спасибо

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Я не уверен, что понимаю вашу цель. Я пишу следующий ответ с предположением, что вы хотите совпадать с именем пути POSIX. Так как в Linux / Unix имя файла может содержать любые символы, кроме NUL,: и /, это может быть очень сложно (или просто, зависит от того, что вы можете ввести).

Самый простой способ - сопоставить каждую строку, которая не содержит этих символов (за исключением /, потому что это используется в пути):

^[^\x00:]+$

Если мы получим какое-либо совпадение, это означает, что строка может быть именем файла (или полным путем).

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

^[^\x00\n:]+$

Иногда нам нужен только абсолютный путь, поэтому мы сопоставляем / в начале строки:

^/[^\x00\n:]+$

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

^(/[^\x00\n:/]*){3,}$

Мы можем добавить больше ограничений к именам файлов, но вы поймете, что нужно.

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

0 голосов
/ 15 апреля 2019

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

(^\/[^/]*)[(\/[^/]*)?]*
           ^       ^

Если вы исправите это, поместив его вне класса персонажей, вы получите дополнительную группу захвата, за которой следует повторение 0+ раз ] в конце.

Если вы повторите только вторую группу захвата, в этой группе будет только результат последней итерации .

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

(^\/[^/\n]*)((?:/[^/\n]+)*)
  • ( Группа захвата 1
    • ^\/[^/\n]* Утверждение начала строки, совпадение /, за которым следует отрицательный класс символов, который также соответствует символу новой строки
  • ) Закрыть группу
  • ( Захватывающая группа 2
    • (?:/[^/\n]+)* Повторите 0+ раз соответствия /, за которым следует отрицательный класс символов
  • ) Закрыть группу

regex demo

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