Регулярные выражения Perl и их применение


         

Преобразование ftp и http ссылок в теги HTML


Возьмем такой текст:

Зайдите на www.intuit.ru и посмотрите список курсов

Здесь текст www.intuit.ru является ссылкой, несмотря на отсутствие протокола http://, который подразумевается по умолчанию. В итоге наше регулярное выражение должно преобразовать этот текст к такому виду:

Зайдите на <a href="http://www.intuit.ru" target="_blank"> www.intuit.ru</a> и посмотрите список курсов

Может быть и так, что ссылка не отделена пробелом от окружающих слов или после нее идет знак препинания (точка, запятая и т.д.) Желательно, чтобы регулярное выражение это учитывало и не включало такой знак в ссылку. И конечно, оно не должно совпадать там, где ему совпадать не следует. Неплохо было бы, если бы оно также форматировало текст ссылки href: протокол, домен и субдомены должны быть записаны строчными буквами. А сам текст, который будет виден на странице, должен оставаться таким, каким его ввел участник форума. Задача эта непростая и не формализуется. Критерием успешности регулярного выражения является то, как оно справляется с набором тестов, которые провоцируют его к несовпадению или совпадению не в тех местах.

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

Протокол может быть http, https и ftp. Для его обнаружения создадим строковую переменную $protocol:

my $protocol='(?:(?=[FfHh])(?i:http(?>s?)|ftp)://)';

Если в тексте следующий символ F, f, H или h, то этот подшаблон делает проверку следующих за ним символов и, если это протокол, поглощает его вместе с префиксом. Я взял весь шаблон для протокола в скобки, потому что в общем регулярном выражении у этого подшаблона может стоять квантификатор, который должен относиться ко всему этому подшаблону, а не к последнему его символу /.

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

my $host=<<HOST; (?>[A-Za-z0-9]{1,63}\\.) (?>[A-Za-z0-9] (?>[-A-Za-z0-9]{0,62})\\. )* HOST




Содержание    Вперед