2014-01-27 13 views
1

Я пытаюсь извлечь информацию из списка папок, которые организованы логически, но имеют необязательные части.Строковая маска в perl для изменений формата версии

Ниже моя структура папок с необязательными полями отмечено в <>:

artist - album_nr. album_title <(type)> <(issue_info)> (year) [quality] 

Так некоторые примеры каталогов будут называться как этот

Emperor - 03. Reverence (EP) (1997) [flac] 
Emperor - 05b. IX Equilibrium (reissue 2007) (1999) [cue-flac] 
Exodus - 01a. Bonded By Blood (1985) [cue-flac] 
Exodus - 01b. Bonded By Blood (remaster 2008) (1985) [cue-flac] 
Exodus - 03.Tempo of the Damned (EP) (remaster 2008) (1985) [cue-flac] 

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

В лучшем случае массив будет содержать 7 фрагментов информации и 5 единиц информации, по крайней мере.

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

+1

_ Мне нужно regex_ ... Нет, вам нужно сначала изучить регулярное выражение. – Jerry

+0

Это полезно. Я использую регулярное выражение однажды в синей луне, чтобы сделать некоторую обработку, которую мне может понадобиться для личного использования дома. Поскольку это примерно один раз каждые 18 месяцев, я забываю об этом так быстро, как только узнаю. Проблема, вероятно, тривиальна для тех, кто использует ее день в/из, но не для тех, кто использует совершенно разные методы программирования. – Reptile

+1

@ Reptile: Проблема в том, что большинство людей на сайте здесь, чтобы помочь друг другу учиться. Когда вы говорите, что вам не интересно учиться, вы говорите, что людям нечем помочь. – ruakh

ответ

1

Использование расширенного обозначения для читаемости:

my $re = qr/ 
    ([^-]+?)   # artist 
    \h*    # 
    -     # literal '-' 
    \h*    # 
    ([0-9]+[a-z]?) # album number 
    \.    # literal '.' 
    \h*    # 
    ([^(]+?)   # album title 
    \h*    # 
    (?:\(([^)]+)\))? # type (optional) 
    \h*    # 
    (?:\(([^)]+)\))? # issue info (optional) 
    \h*    # 
    \(([^)]+)\)  # year 
    \h*    # 
    \[(.+)\]   # quality 
/x; 

Обратите внимание, что это регулярное выражение всегда возвращает семь значений (на матче), потому что есть семь захватов.

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

(?: # begin non-capturing grouping (for '?' quantifier at the end) 
\( # literal '(' 
(  # begin capture 
[^)]+ # any character other than ')', one or more times 
)  # end capture 
\)  # literal ')' 
)  # end non-capturing grouping 
?  # zero or one quantifier (make everything in group optional) 

Edit: В комментариях, Джерри правильно указывает, что существует потенциальная неоднозначность о том, что соответствует, когда только один из дополнительных полей (типа или выдавать данные) присутствует в данные. Это можно устранить, сделав реджикс менее разрешительным (рискуя не соответствовать некоторым данным - всегда проверяйте, было ли совпадение успешным). Это работает для данных выборки вы предоставили:

(?:\((\w+\h+[0-9]{4}+)\))? # issue info (optional) 

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

\(([0-9]{4})\) # year 
+0

Спасибо! Я буду работать с этим и посмотреть, как это происходит, и опубликовать окончательный результат. – Reptile

+0

Я бы использовал несколько другое регулярное выражение, если бы был вами. Идея хорошая, но если каждое из полей важно, то вы не должны получать поле 'issue_info', в котором должно быть поле' type'. Вы видите это более ясным с именованными захватами: [link] (http: // regex101.com/r/gT8gM1) в отличие от [link] (http://regex101.com/r/vN0zN0). OP не упоминает все правила, но это касается того, о чем сообщает образец. – Jerry

+0

Да, ваша вторая ссылка обеспечивает более надежное соответствие указанной информации. Спасибо за вклад каждого. Теперь у меня есть база для работы, поэтому я могу улучшить другие области процесса извлечения. Я надеюсь использовать это, чтобы заполнить теги в моей коллекции этой информацией. – Reptile

Смежные вопросы