Является ли Perl или нет, иногда проблема с регулярным выражением - это его жадность.Скажем, я хочу, чтобы захватить первое имя кого-то и строка выглядит следующим образом:
Bob Baker
Я мог бы использовать это регулярное выражение:
sed 's/^\(.*)\ .*$/\1/'
Это будет работать с Боб Бейкер, но не с Боб Барри Бейкер. Проблема в том, что мое регулярное выражение жадное и выберет все символы до последнего места, поэтому я бы не закончил с Bob
, а с Bob Baker
. Обычный способ решить это указать все символы, кроме на тот, который вы не хотите:
sed 's/^\([^ ]*)\ .*$/\1/'
В этом случае, я указав любой набор символов не включая пространство. Это изменит как Bob Baker
, так и Bob Rudolph Baker
на Bob
.
У Perl есть другой способ указать неживое регулярное выражение. В Perl вы добавляете ?
к своему суб-выражению, которое вы хотите быть не жадным. В приведенном выше примере, оба из них изменит строку, содержащую Bob Barry Baker
только Bob
:
$string =~ s/^([^ ]+) .*$/$1/;
$string =~ s/^(.+?) .*$/$1/;
Кстати, это не эквивалент!
С все, кроме космического регулярного выражения, я мог бы сделать это:
$string =~ /^([^ ]+)()(\[\d{4}\])()(\(\d+p\))(\.)([^.]+)/
С нежадным классификатором:
$string =~ /^(.+?)()(\[\d{4}\])()(\(\d+p\))(\.)(.*)/
И, используя x
классификатор, который позволяет вам поместите одно и то же регулярное выражение на несколько строк, что приятно, потому что вы можете добавлять комментарии, чтобы помочь объяснить, что вы делаете:
$string =~/
^(.+?) #Any set of characters (non-greedy)
([ ]) #Space
(\[\d{4}\]) #[1959]
([ ]) #Space
(\([0-9]+p\)) #(430p)
[.] #Period
([^\.]+) #File Suffix (no period)
/x
И в этот момент вы могли бы также следовать рекомендациям Даниина Конвей Рекомендации по регулярным выражениям на языке Перл.
$string =~/
\A #Start of Regular Expression Anchor
(.+?) #Any set of characters (non-greedy)
([ ]) #Space
(\[ \d{4} \]) #[1959]
([ ]) #Space
(\([0-9] +p \)) #(430p)
([.]) #Period
([^\.]+) #File Suffix (no period)
\Z #End of string anchor
/xm;
Поскольку x
игнорирует всех белого пространства, я даже могу добавить пробелов между подгруппами по одной и той же линии. В этом случае (.*+?)
немного чище, чем (.*+?)
. (\([0-9] +p \))
или (\([0-9]+p \))
или даже (\([0-9]+p\))
проще понять, зависит от вас.
И, да, ответ очень похож на Sinan's ответ.
Кстати, как показало Sinan, используя нежадный регулярные выражения спецификатора способно анализировать a b c d e [1234] (1080p).mov
при использовании все, что не включает в себя подвыражение пространства не будет.Вот почему я сказал, что они не то же самое.
Я только понял, насколько непонятно, что я изначально был. Я также заметил, что у меня была ошибка в моих предыдущих предположениях. Я пошел вперед и полностью переформулировал его для ясности. Надеюсь, это поможет, извините за предыдущую путаницу. – TehTechGuy
Извините, это была моя неряшливость, когда я редактировал комментарий. Эти теги были добавлены, и я забыл удалить теги close. – TehTechGuy