Python regex - извлечение каталогов из пути - PullRequest
3 голосов
/ 14 февраля 2012

У меня есть вопрос о регулярном выражении / Python.Извините, если эту тему обсуждали миллионы раз - обычно я нахожу ответы на so / google и т. Д., Но я застрял в миллионах ответов с этим ... (Если честно - у меня есть книга регулярных выражений, но как-тоЯ слишком глуп, чтобы действительно понять это ...)

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

Если путь: (Случай 1)

"/The Prodigy/The Fat Of The Land/04 - Funky Stuff.flac"
, он должен извлечь:
  • Artist: "The Prodigy"
  • release: "Жир Земли "
  • Номер трека: 4
  • Название:" Funky Stuff "

И, например: (Дело 2)

"/[XLR 483] The Fat Of The Land/04 - The Prodigy - The  Funky Stuff.flac"
следует извлечь:
  • катно: "XLR 483"
  • выпуск: "Жир Земли"
  • номер трека: 4
  • художник: "The Prodigy"
  • Title:" Funky Stuff "

Нет необходимости в регулярном выражении, которое охватывает оба случая, это всего лишь два примера.Затем я предоставлю их в качестве параметров (или отправную точку для добавления собственных).

Любая помощь будет принята с благодарностью!

@ S.Lott: У меня нет регулярного выражениядля этого я начал с разделения строки:

parts = rel_path.split('/')       
track = parts[-1]
release = parts[-2]
artist = parts[-3]

, но для меня это выглядит крайне негибким и не элегантным решением.

edit:

Пока чтоУ меня есть что-то вроде:

pattern = re.compile('^/(?P<artist>[a-zA-Z0-9 ]+)/(?P<release>[a-zA-Z0-9 ]+)/(?P<track>[a-zA-Z0-9 -_]+).[a-zA-Z]*.*')


rel_path = '/The Prodigy/The Fat Of The Land/04 - Funky Stuff.flac'

match = pattern.search(rel_path)

artist = match.group('artist')
release = match.group('release')
track = match.group('track')

Ответы [ 4 ]

6 голосов
/ 14 февраля 2012

Хотя это и не обязательно, но это удобный выбор для этой проблемы.

import re
pattern = re.compile(r"/(?P<artist>[a-zA-Z0-9 ]+?)/(?P<release>[a-zA-Z0-9 ]+?)/(?P<tracknumber>\d+?) - (?P<title>[a-zA-Z0-9 ]+?).flac")
s = "/The Prodigy/The Fat Of The Land/04 - Funky Stuff.flac"
m = pattern.search(s)
print m.group('artist')
print m.group('release')
print m.group('track number')
print m.group('title')

Я использую выражения, такие как [a-zA-Z0-9 ], чтобы явно указать символы, которые я ожидаю в строке.Я просто предпочитаю использовать регулярные выражения в виде белого списка, чтобы сделать код более безопасным.Есть много других способов составления эквивалентных шаблонов.Здесь вы найдете все, что вам нужно http://docs.python.org/library/re.html, вам не нужна книга для этого.

2 голосов
/ 14 февраля 2012
pattern1 = re.compile(r'/([^/]*)/([^/]*)/([0-9]*) - (.*)\.[^.]*')
artist,release,Tracknumber,Title = pattern1.match(file1).groups()

pattern2 = re.compile(r'/\[([^]]*)\] ([^/]*)/([0-9]*) - (.*) - (.*)\.[^.]*')
catno,release,Tracknumber,artist,Title = pattern2.match(file2).groups()

(где file1 и file2 - пути, которые вы указали выше).

Первое: вы захватываете что-то, сопоставленное регулярному выражению с круглыми скобками. Таким образом, все, что находится в скобках ниже, будет отображаться как элемент в матче.

Второе: вы сопоставляете все, кроме косой черты, с кодом регулярного выражения, например [^/]. Таким образом, чтобы соответствовать многим вещам между косыми чертами, вы делаете [^/]*.

Соединяя их вместе, чтобы захватить художника в вашей первой строке, вы делаете /([^/]*)/. Затем вы делаете это снова, чтобы получить релиз.

В-третьих: для совпадения с любой цифрой вы используете [0-9]. Таким образом, чтобы соответствовать любой строке цифр, вы используете [0-9]*.

Повторно применяйте эти принципы, и вы сможете понять вышесказанное.

0 голосов
/ 14 февраля 2012

Вы должны сначала использовать split с разделителем /, чтобы иметь возможность получать информацию только с размером массива, возвращаемого split.

Тогда вы можете использовать регулярные выражения, если вам нужно. Например, во втором случае: (что происходит, только если у вас есть два элемента, верно?)

import re
item = "/[XLR 483] The Fat Of The Land/04 - The Prodigy - The  Funky Stuff.flac"
matches = re.search('^\/?\[([^\]]+)](.*)\/', item)
print matches.group(1) # 'XLR 483'
print matches.group(2) # ' The Fat Of The Land'

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

  1. ^ в начале
  2. /? может быть не более одного слэша /, за которым следует ...
  3. [ фигурная скобка
  4. ([^\]]+), содержащий все, кроме закрывающей фигурной скобки, один или несколько раз + (и, пожалуйста, введите значения, используя круглые скобки) и
  5. ] закрывающая фигурная скобка, за которой следует
  6. (.*) все, кроме перевода строки (0 или более раз *), захваченное через круглые скобки
  7. и косая черта /.

надеюсь, это поможет!

0 голосов
/ 14 февраля 2012

Вот мой подход к проблеме, с которой вы столкнулись.

  1. Выполните разбиение пути и проверьте, имеет ли он значение len 4 (первый случай) или 3 (второй случай).
  2. Игнорировать первый элемент, который должен быть одним символом '/', а для второго элемента действовать, чтобы извлечь [xxx].
  3. Разделите на '-' последний элемент, чтобы получить другую информацию.

Если у вас есть какие-то конкретные сомнения, при написании регулярных выражений отредактируйте свой вопрос и следуйте предложению S.Lott.

...