Skip to content

Latest commit

 

History

History
327 lines (226 loc) · 14.6 KB

File metadata and controls

327 lines (226 loc) · 14.6 KB

Python FilePathParser

Читать на английском

Универсальная расширяемая библиотека Python для извлечения структурированной информации (группы, даты, время, кастомные паттерны) из имён файлов и путей.

  • Без жёстко заданной логики: вы выбираете любое количество групп (списки, Enum, dict, строки).
  • Автоматический поиск дат и времени (поддержка и валидация множества форматов).
  • Неограниченные кастомные паттерны: добавляйте свои regex-группы.
  • Гибкий приоритет: важнее имя файла или путь — вы решаете.
  • Работает с str и pathlib.Path.
  • Возвращает None, если не найдено или не валидно.
  • Простой интерфейс: используйте только две функции — parse() и create().

Оглавление


Установка

pip install file-path-parser

Поддерживаемые форматы даты и времени

Примеры дат:

  • 20240622 (ГГГГММДД)
  • 2024-06-22 (ГГГГ-ММ-ДД)
  • 2024_06_22 (ГГГГ_ММ_ДД)
  • 22.06.2024 (ДД.ММ.ГГГГ)
  • 22-06-2024 (ДД-ММ-ГГГГ)
  • 220624 (ГГММДД)
  • 2024-6-2, 2024_6_2

Примеры времени:

  • 154212 (ЧЧММСС)
  • 1542 (ЧЧММ)
  • 15-42-12 (ЧЧ-ММ-СС)
  • 15_42_12 (ЧЧ_ММ_СС)
  • 15-42, 15_42 (ЧЧ-ММ, ЧЧ_ММ)

Все даты и время проходят валидацию. Например, "20241341" — не дата, "246199" — не время.


Примеры использования

Весь парсинг делается через интерфейсные функции — используйте только их для чистого API:

1. Быстрый однострочник (основной сценарий)

from file_path_parser.api import parse

result = parse(
    "cat_night_cam15_20240619_1236.jpg",
    ["cat", "dog"], ["night", "day"],
    date=True, time=True, patterns={"cam": r"cam\d{1,3}"}
)
print(result)
# {'group1': 'cat', 'group2': 'night', 'date': '20240619', 'time': '1236', 'cam': '15'}

2. Создание переиспользуемого парсера

from file_path_parser.api import create

parser = create(
    ["cat", "dog"], ["night", "day"],
    date=True, time=True, patterns={"cam": r"cam\d{1,3}"}
)
result = parser.parse("dog_night_cam22_20240620_0815.jpg")
print(result)
# {'group1': 'dog', 'group2': 'night', 'date': '20240620', 'time': '0815', 'cam': '22'}

Больше примеров: Dict, Enum, приоритет, и др.

from enum import Enum
from file_path_parser.api import parse

class Status(Enum):
    OPEN = "open"
    CLOSED = "closed"

result = parse(
    "open_beta_cam21_20231231_2359.txt",
    Status, ["beta", "alpha"],
    date=True, time=True, patterns={"cam": r"cam\d{2}"}
)
print(result)
# {'status': 'open', 'group1': 'beta', 'date': '20231231', 'time': '2359', 'cam': '21'}

Если и путь, и имя файла содержат группу — побеждает параметр priority.

from file_path_parser.api import parse

result = parse(
    "/data/prod/archive/test_20240620.csv",
    ["prod", "test"], date=True, priority="filename"
)
print(result)
# Если priority="filename", group1 == "test"
# Если priority="path", group1 == "prod"

API

from file_path_parser.api import parse, create

def parse(full_path: str, *groups, date=False, time=False, separator="_", priority="filename", patterns=None) -> dict:
    '''
    Однострочный парсинг.
    '''

def create(*groups, date=False, time=False, separator="_", priority="filename", patterns=None) -> FilePathParser:
    '''
    Возвращает объект-парсер для многократного использования.
    '''
  • Имена групп генерируются автоматически:

    • Enum: имя класса в нижнем регистре.
    • Dict: ключ как имя группы.
    • List/tuple/set: groupN (N — номер по порядку).
    • String: значение как имя группы.
  • Если группа не найдена или невалидна: будет None для этой группы.

  • Дата и время всегда валидируются (если невалидны — None).

  • Кастомные паттерны: возвращается только число (например, cam1515).


Как это работает

  1. Делит имя файла и путь на “блоки” (по _, -, ., / и др.).

  2. Для каждой группы ищет точное совпадение (для Enum, списков, dict).

  3. Для date и time:

    • Находит все поддерживаемые форматы через regex.
    • Валидирует через datetime.strptime.
  4. Для кастомных паттернов:

    • Использует ваши regex-паттерны.
    • Возвращает только число (если паттерн типа cam\d+, результат — '15' для cam15). Если нужен весь матч, используйте скобки: patterns={"cam": r"(cam\d+)"}

Если и путь, и имя файла содержат группу — значение берётся согласно priority.


Заметки

  • Имя группы в результате будет None, если не найдено или невалидно.
  • Если и путь, и имя файла содержат группу, выигрывает значение по приоритету.
  • Можно использовать любое количество групп и паттернов — нет лимита.
  • PatternMatcher.find_special: Это внутренняя функция, не используется по умолчанию, но может быть полезна для продвинутых сценариев (например, для тестирования или прямого поиска паттерна в строке).

CLI — командная строка для FilePathParser

Библиотека поддерживает удобный CLI для извлечения структурированной информации прямо из имени файла/пути.


🚀 Быстрый старт

После установки зависимостей через Poetry можно использовать file-path-parser прямо из терминала.

Пример использования

poetry run file-path-parser "cat_night_cam15_20240619_1236.jpg" --groups cat dog --classes night day --date --time --pattern cam "cam\d{1,3}"

Помощь

poetry run file-path-parser --help

Опции CLI

  • filepath — Путь или имя файла для парсинга
  • --groups — Список допустимых групп (например, cat dog)
  • --classes — Список допустимых классов (например, night day)
  • --date — Включить парсинг дат
  • --time — Включить парсинг времени
  • --pattern NAME REGEX — Добавить кастомный паттерн (можно использовать несколько раз)

Пример

poetry run file-path-parser "dog_day_cam2_20240701_0800.jpg" --groups cat dog --classes night day --date --time --pattern cam "cam\d{1,3}"

Результат будет выведен в терминал.


PatternMatcher.find_special (продвинутое использование)

Примечание Этот метод не используется по умолчанию в основном API. Предназначен для продвинутых пользователей или интеграционного тестирования, может пригодиться если нужно напрямую достать паттерн (дату, время или кастомную группу) из строки.

Вы можете использовать PatternMatcher.find_special для поиска даты, времени или своей группы прямо в имени файла или строке. Для кастомных паттернов возвращается только число (например, "15" для "cam15").

from file_path_parser.file_path_parser import PatternMatcher

matcher = PatternMatcher(user_patterns={"cam": r"cam\d{2}"})
print(matcher.find_special("foo_cam15_20240619.txt", "cam"))  # Вывод: "15"
print(matcher.find_special("foo_20240619.txt", "date"))       # Вывод: "20240619"
print(matcher.find_special("foo_1531bar.txt", "time"))        # Вывод: "1531"

Как помочь проекту

  • Любые Pull Request, баг-репорты и предложения приветствуются!
  • Все доработки, новые функции и исправления отправляются через Pull Request в ветку develop.
  • Ветка main используется только для стабильных релизов.
  • Перед мержем любые изменения проходят код-ревью.
  • Весь код должен быть типизирован (mypy), отформатирован (black) и покрыт тестами (pytest).
  • Создавайте Issue, даже если не готовы реализовать фичу сами — любые идеи и замечания важны.
  • Хотите стать контрибьютором? Делайте форк, создавайте ветку от develop, отправляйте Pull Request или пишите напрямую (см. контакты). Любая помощь и идеи приветствуются!

Project Board

Весь прогресс по задачам, планированию и развитию библиотеки виден в Project Board.

  • Смотрите, что в работе, что запланировано и что уже сделано
  • Следите за дорожной картой и развитием фич
  • Предлагайте улучшения или багрепорты через Issues, которые напрямую связаны с доской

Открыть Project Board →


FAQ / Известные проблемы

В: Что если и путь, и имя файла содержат одну и ту же группу, но с разными значениями?

О: Итог зависит от параметра priority:

  • Если priority="filename" (по умолчанию), побеждает значение из имени файла.
  • Если priority="path" — значение из пути.

В: Можно ли использовать не-латиницу или Unicode в значениях групп?

О: Да. Совпадения ищутся без учёта регистра и поддерживают Unicode.

В: Какие разделители парсер воспринимает между блоками?

О: По умолчанию разбивает по: _, -, ., /, \, {}, или пробелу. Если у вас экзотические разделители — дайте знать!

В: Что если значение похоже на дату/время, но не является настоящим?

О: Парсер валидирует все даты/время. "20241341" (неверный месяц/день) не будет распознано как дата и т.п.

В: Что возвращается для кастомных паттернов?

О:

  • Если, например, patterns={"cam": r"cam\d+"}, вы получите только число, напр., 'cam15''15'.
  • Если нужен весь матч (например, 'cam15'), используйте скобки: patterns={"cam": r"(cam\d+)"}.

Известные проблемы

  • Если у вас экзотический разделитель (не из списка выше), возможно потребуется предварительная обработка имени файла.
  • Очень редкие форматы дат/времени (не из списка) не парсятся.
  • Парсинг путей поддерживает и str, и pathlib.Path, но сетевые/кроссплатформенные пути (UNC, SMB) специально не тестировались.

Автор

Telegram GitHub


Лицензия

MIT