Regex для разбора каталога и имени файла

Вопрос:Я пытаюсь написать регулярное выражение, которое будет анализировать каталог и имя файла для полного пути, используя соответствующие группы. так... /var/log/xyz/10032008.log распознает group 1 to be "/var/log/xyz" и group 2 to be "10032008.log" Кажется простым, но я не могу заставить соответствующие группы работать для меня. ПРИМЕЧАНИЕ. Как отмечают некоторые респонденты, это, вероятно, не очень хорошо использует

Вопрос:

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

так…

/var/log/xyz/10032008.log

распознает group 1 to be «/var/log/xyz» и group 2 to be «10032008.log»

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

ПРИМЕЧАНИЕ. Как отмечают некоторые респонденты, это, вероятно, не очень хорошо использует регулярные выражения. Обычно я бы предпочел использовать API-интерфейс файла, который я использовал. То, что я на самом деле пытаюсь сделать, немного сложнее, чем это, но было бы гораздо труднее объяснить, поэтому я выбрал домен, с которым все будут знакомы, чтобы наиболее кратко описать проблему с корнем.

Лучший ответ:

Попробуйте следующее:

^(.+)/([^/]+)$ Ответ №1

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

((?:[^/]*/)*)(.*)

Я объясню gnarly regex, взорв его…

( (?: [^/]* / ) * ) (.*)

Что означают части:

( — capture group 1 starts (?: — non-capturing group starts [^/]* — greedily match as many non-directory separators as possible / — match a single directory-separator character ) — non-capturing group ends * — repeat the non-capturing group zero-or-more times ) — capture group 1 ends (.*) — capture all remaining characters in group 2 Содержание

  1. Пример
  2. Обоснование:
  3. результат
  4. Шаг за шагом процесс создания регулярного выражения
  5. Шаблон Объяснение
  6. Шаг 1: Начните с соответствия root каталога
  7. Шаг 2: Попробуйте найти первый каталог.
  8. Шаг 3: Получить полный путь к каталогу для файла
  9. Шаг 4: сопоставьте имя файла и очистите
  10. Правила Regex, используемые выше, перечислены здесь

Пример

Чтобы проверить регулярное выражение, я использовал следующий Perl script…

#!/usr/bin/perl -w use strict; use warnings; sub test { my $str = shift; my $testname = shift; $str =~ m#((?:[^/]*/)*)(.*)#; print «$str — $testnamen»; print » 1: $1n»; print » 2: $2nn»; } test(‘/var/log/xyz/10032008.log’, ‘absolute path’); test(‘var/log/xyz/10032008.log’, ‘relative path’); test(‘10032008.log’, ‘filename-only’); test(‘/10032008.log’, ‘file directly under root’);

Вывод script…

/var/log/xyz/10032008.log — absolute path 1: /var/log/xyz/ 2: 10032008.log var/log/xyz/10032008.log — relative path 1: var/log/xyz/ 2: 10032008.log 10032008.log — filename-only 1: 2: 10032008.log /10032008.log — file directly under root 1: / 2: 10032008.log Ответ №2

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

Предполагая, что/является ограничителем пути…

^(.*/)([^/]*)$

Первой группой будет любая информация о каталоге/пути, вторая будет именем файла. Например:

  • /foo/bar/baz.log: “/foo/bar/” – это путь, “baz.log” – это файл
  • foo/bar.log: “foo/” – это путь, “bar.log” – это файл
  • /foo/bar: “/foo/” – это путь, “bar” – это файл
  • /foo/bar/: “/foo/bar/” – это путь, и файл отсутствует.

Ответ №3

Какой язык? и зачем использовать регулярное выражение для этой простой задачи?

Если вы должны:

^(.*)/([^/]*)$

дает вам две части, которые вы хотели. Вам может потребоваться указать круглые скобки:

^(.*)/([^/]*)$

в зависимости от вашего предпочтительного синтаксиса языка.

Но я предлагаю вам просто использовать функцию поиска строки на языке, которая находит последний символ “/” и разбивает строку на этот индекс.

Ответ №4

Как насчет этого?

[/]{0,1}([^/]+[/])*([^/]*)

Детерминистский:

((/)|())([^/]+/)*([^/]*)

Строгий:

^[/]{0,1}([^/]+[/])*([^/]*)$ ^((/)|())([^/]+/)*([^/]*)$ Ответ №5

Попробуйте следующее:

/^(/([^/]+/)*)(.*)$/

Он оставит конечную косую черту на пути.

Ответ №6

Очень поздний ответ, но надеюсь, что это поможет

^(.+?)/([w]+.log)$

Это использует ленивый чек для /, и я только что изменил принятый ответ

http://regex101.com/r/gV2xB7/1

Ответ №7

Обоснование:

Я провел небольшое исследование методом проб и ошибок. Выяснилось, что все значения, доступные на клавиатуре, могут быть файлом или каталогом, кроме ‘/’ в * nux machine.

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

(Значения, разделенные запятыми ниже)
‘!’, ‘@’, ‘#’, ‘$’, “‘”,’% ‘,’ ^ ‘,’ & ‘,’ * ‘,’ (‘,’) ‘,’ ‘,’ “‘, ‘’, ‘-‘, ‘,’, ‘[‘, ‘]’, ‘{‘, ‘}’, ” ‘,’ ~ ‘,’> ‘,’ <‘,’ = ‘,’ + ‘,’; ‘,’: ‘,’ | ‘

Это не удалось, только когда я попытался создать ‘/’ (потому что это корневой каталог) и имя файла контейнера / потому что это разделитель файлов.

И это изменило время модификации текущего каталога . когда я touch. , Однако file.log возможен.

И, конечно же, az, AZ, 0-9, — (hypen), _ (подчеркивание) должны работать.

результат

Итак, по приведенным выше рассуждениям мы знаем, что имя файла или имя каталога может содержать все, кроме косой черты / forward. Таким образом, наше регулярное выражение будет получено из того, что не будет присутствовать в имени файла/имени каталога.

/(?:(?P<dir>(?:[/]?)(?:[^/]+/)+)(?P<filename>[^/]+))/

Шаг за шагом процесс создания регулярного выражения

Шаблон Объяснение

Шаг 1: Начните с соответствия root каталога

Каталог может начинаться с / когда он является абсолютным путем, и именем каталога, когда он относительный. Следовательно, ищите / с нуля или одного вхождения.

/(?P<filepath>(?P<root>[/]?)(?P<rest_of_the_path>.+))/

Шаг 2: Попробуйте найти первый каталог.

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

/(?P<filepath>(?P<first_directory>(?P<root>[/]?)[^/]+/)(?P<rest_of_the_path>.+))/

Шаг 3: Получить полный путь к каталогу для файла

Далее пусть совпадут все каталоги

/(?P<filepath>(?P<dir>(?P<root>[/]?)(?P<single_dir>[^/]+/)+)(?P<rest_of_the_path>.+))/

Здесь single_dir – это yz/ потому что сначала он соответствовал var/, затем он обнаружил следующее вхождение того же шаблона, то есть log/, затем он обнаружил следующее вхождение того же шаблона yz/. Итак, это показало последнее появление паттерна.

Шаг 4: сопоставьте имя файла и очистите

Теперь мы знаем, что никогда не будем использовать такие группы, как single_dir, filepath, root. Поэтому позвольте это убрать.

Пусть держат их как группы, но не захватывают эти группы.

И rest_of_the_path – это просто имя файла! Итак, переименуйте его. И файл не будет иметь / в своем названии, поэтому лучше сохранить [^/]

/(?:(?P<dir>(?:[/]?)(?:[^/]+/)+)(?P<filename>[^/]+))/

Это подводит нас к конечному результату. Конечно, есть несколько других способов сделать это. Я просто упоминаю один из способов здесь.

Правила Regex, используемые выше, перечислены здесь

^ означает, что строка начинается с
(?P<dir>pattern) означает захват группы по имени группы. У нас есть две группы с именем группы dir и file
(?:pattern) означает, что не следует рассматривать эту группу или группу без захвата.
? означает совпадение ноль или единицу. + означает совпадение с одним или несколькими [^/] означает совпадение с любым символом кроме косой черты (/)

[/]? означает, что если это абсолютный путь, то он может начинаться с /, иначе не будет. Итак, сопоставьте ноль или одно вхождение /.

[^/]+/ означает один или несколько символов, которые не являются косой чертой (/), за которой следует косая черта (/). Это будет соответствовать var/ или xyz/. Один каталог за раз.

Ответ №8

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

Оцените статью
Добавить комментарий