Отчасти это будет зависеть от вашего знакомства с Objective-C и его API.
Сказав это, книга Hilleglass Cocoa и книга Дейва Марка оба превосходны (особенно книга Дэйва Марка). Я еще не читал книгу «Ранчо большого ботаника», но эти двое - «должны иметь». Книга Дейва Марка опускает все остальные книги по программированию для iPhone.
В дополнение к тем, которые вы, вероятно, хотите подробно рассмотреть «Шаблоны проектирования какао» Эрика Бака и «Программирование в Objective-C 2.0» Стивена Кочана. API-интерфейсы Cocoa находятся под сильным влиянием шаблонов проектирования, и понимание того, как их использовать, а также семантики языка будет иметь большое значение.
Возможно, вы захотите добавить пару конкретных книг по некоторым API-интерфейсам Cocoa, в частности, по Core Data и Core Animation. Очень хорошее понимание базовых данных навсегда изменит ваши возможности кодирования. Лучшая книга на эту тему - «Прагматическая» Маркуса Зарры.
Наличие более пары книг - это всегда хорошо ...; -)
Предполагая, что вы проанализировали файл конфигурации, чтобы получить список расширений и игнорируемых каталогов, вы можете построить регулярное выражение в виде строки, а затем использовать оператор qr
чтобы скомпилировать его в регулярное выражение:
my @extensions = qw(avi flv mp3 mp4 wmv); # parsed from file
my $pattern = '\.(' . join('|', @wanted) . ')$';
my $regex = qr/$pattern/;
if ($file =~ $regex) {
# do something
}
Компиляция не является строго необходимой; вы можете использовать строковый шаблон напрямую:
if ($file =~ /$pattern/) {
# do something
}
Каталоги немного сложнее, потому что у вас есть две разные ситуации: полные имена и суффиксы. Ваш файл конфигурации должен будет использовать разные ключи, чтобы было понятно, что есть что. например, «dir_name» и «dir_suffix». Для полных имен я бы просто построил хэш:
%ignore = ('.svn' => 1);
Каталоги с суффиксами могут быть созданы так же, как и расширения файлов:
my $dir_pattern = '(?:' . join('|', map {quotemeta} @dir_suffix), ')$';
my $dir_regex = qr/$dir_pattern/;
Вы даже можете встроить шаблоны в анонимные подпрограммы, чтобы избежать ссылок на глобальные переменные:
my $file_filter = sub { $_ =~ $regex };
my $descend_filter = sub {
! $ignore{$File::Next::dir} &&
! $File::Next::dir =~ $dir_regex;
};
my $iter = File::Next::files({
file_filter => $file_filter,
descend_filter => $descend_filter,
}, $directory);
Допустим, вы используете Config :: General для своего конфигурационного файла и что он содержит следующие строки:
<MyApp>
extensions avi flv mp3 mp4 wmv
unwanted frames svn
</MyApp>
Затем вы можете использовать его так (см. Config :: General для получения дополнительной информации):
my $conf = Config::General->new('/path/to/myapp.conf')->getall();
my $extension_string = $conf{'MyApp'}{'extensions'};
my @extensions = split m{ }, $extension_string;
# Some sanity checks maybe...
my $regex_builder = join '|', @extensions;
$regex_builder = '.(' . $regex_builder . ')$';
my $regex = qr/$regex_builder/;
if($file =~ m{$regex}) {
# Do something.
}
my $uw_regex_builder = '.(' . join ('|', split (m{ }, $conf{'MyApp'}{'unwanted'})) . ')$';
my $unwanted_regex = qr/$uw_regex_builder/;
if(File::Next::dir !~ m{$unwanted_regex}) {
# Do something. (Note that this does not enforce /^.svn$/. You
# will need some kind of agreed syntax in your conf-file for that.
}
(Это полностью не проверено.)
Создайте его, как обычную строку, а затем используйте интерполяцию в конце, чтобы превратить ее в скомпилированное регулярное выражение. Также будьте осторожны, вы не сбежите. или помещая его в класс символов, поэтому он означает любой символ (а не буквальную точку).
#!/usr/bin/perl
use strict;
use warnings;
my (@ext, $dir, $dirp);
while (<DATA>) {
next unless my ($key, $val) = /^ \s* (ext|dirp|dir) \s* = \s* (\S+)$/x;
push @ext, $val if $key eq 'ext';
$dir = $val if $key eq 'dir';
$dirp = $val if $key eq 'dirp';
}
my $re = join "|", @ext;
$re = qr/[.]($re)$/;
print "$re\n";
while (<>) {
print /$re/ ? "matched" : "didn't match", "\n";
}
__DATA__
ext = avi
ext = flv
ext = mp3
dir = .svn
dirp= .frames
Достаточно просто с File :: Find :: Rule, просто случай создания списка заранее.
use strict;
use warnings;
use aliased 'File::Find::Rule';
# name can do both styles.
my @ignoredDirs = (qr/^.svn/, '*.frames' );
my @wantExt = qw( *.avi *.flv *.mp3 );
my $finder = Rule->or(
Rule->new->directory->name(@ignoredDirs)->prune->discard,
Rule->new->file->name(@wantExt)
);
$finder->start('./');
while( my $file = $finder->match() ){
# Matching file.
}
Тогда это просто случай заполнения этих массивов. (Примечание: приведенный выше код также не протестирован, но, вероятно, будет работать). Я обычно использую для этого YAML, это облегчает жизнь.
use strict;
use warnings;
use aliased 'File::Find::Rule';
use YAML::XS;
my $config = YAML::XS::Load(<<'EOF');
---
ignoredir:
- !!perl/regexp (?-xism:^.svn)
- '*.frames'
want:
- '*.avi'
- '*.flv'
- '*.mp3'
EOF
my $finder = Rule->or(
Rule->new->directory->name(@{ $config->{ignoredir} })->prune->discard,
Rule->new->file->name(@{ $config->{want} })
);
$finder->start('./');
while( my $file = $finder->match() ){
# Matching file.
}
Примечание Использование удобного модуля aliased.pm, который импортирует "File :: Find :: Rule" для меня как "Rule".
Если вы хотите создать потенциально большое регулярное выражение и не хотите утруждать себя отладкой круглых скобок, используйте модуль Perl, чтобы создать его для вас!
use strict;
use Regexp::Assemble;
my $re = Regexp::Assemble->new->add(qw(avi flv mp3 mp4 wmv));
...
if ($file =~ /$re/) {
# a match!
}
print "$re\n"; # (?:(?:fl|wm)v|mp[34]|avi)
Хотя File :: Find :: Rule уже имеет способы справиться с этим, в подобных случаях вам действительно не нужно регулярное выражение. Регулярное выражение здесь не очень выгодно, потому что вы ищете фиксированную последовательность символов в конце каждого имени файла. Вы хотите знать, входит ли эта фиксированная последовательность в список интересующих вас последовательностей. Сохраните все расширения в хеше и посмотрите в него:
my( $extension ) = $filename =~ m/\.([^.]+)$/;
if( exists $hash{$extension} ) { ... }
Вам не нужно создавать регулярное выражение, и вам не нужно выполнять несколько возможных изменений регулярных выражений, чтобы проверить каждое расширение, которое вам нужно исследовать.