Подписка


Подписаться на Google Buzz

Друзья блога

Пульс блога

Опрос

Каких статей следует публиковать больше в блоге?

View Results

Loading ... Loading ...

Система Orphus

Блоги и сообщества

DelphiFeeds.ru - Все Delphi-блоги Рунета О раскрутке блога по программированию

Счётчики


Анализ веб сайтов

Рейтинг блогов

  • 29Sep

    regexpСегодня наконец-то пересилил себя и решил всё-таки изучить вопросы использования регулярных выражений в Delphi.

    Сколько раз не изучал литературу по использованию RegExp, составлению регулярных выражений и пр., всегда казалось, что составить регулярное выражение ужасно сложно, а разобраться в уже написанном выражении – просто нереально. А тут сел и буквально за час с небольшим более-менее разобрался м составил необходимое регулярное выражение.  Дело бы не пошло, если бы не два блога, в которых я нашел всю необходимую информацию по регулярным выражениям, написанных понятным и доступным языком. Поэтому, вначале я хотел бы поделиться с Вами найденной информацией и заодно отблагодарить двух блоггеров пусть не жирной, но всё-таки ссылкой :)

    1. Блог “Парсинг от А до Я“  – здесь я нашел компактную и удобную шпаргалку по регулярным выражением. И не проблема, что шпаргалка на английском языке – те кто хотя бы на школьном уровне знает английский язык разберутся без проблем.

    2. Блог Александра Волкова – Александр поделился информацией по полезным регулярным выражениям, а также предоставил немного информации по составлению регулярных выражений, что было неплохим подспорьем к уже имеющейся шпаргалке.
    Так, что этим ребятам спасибо за прекрасные посты, а мы начнем определять возраст домена. Причем, начиная от импорта необходимых модулей в Delphi и заканчивая готовым приложением на Delphi.

    1. Добавляем RegExp в Delphi 2010.

    RegExp_import_2Прежде, чем начать программировать, необходимо добавить в Delphi библиотеку типов. Для этого запускаем Delphi и выбираем в меню “Componet – Import Component..” В открывшемся окне выбираем “Import a Type Library” и жмем кнопку Next>> В списке доступных библиотек необходимо найти библиотеку Microsoft VBScript Regular Expressions 5.5 . Находим, выбираем и жмем “Next >>“.
    Теперь Вы можете создать невизуальный компонент Delphi 2010 для работы с импортируемой библиотекой. Для этого необходимо задать страницу палитры компонентов на которой будет расположен компонент, поставить галочку “Generate Component Wrappers” и нажать “Next >>“. Я не стал создавать новый компонент, поэтому пропустил этот шаг просто нажав кнопку продолжения в новом окне оставил опцию по умолчанию “Create Unit“.  После того как будет нажата кнопка “Finish” Delphi создаст новый модуль с довольно большим описанием и не менее громоздким названием – VBScript_RegExp_55_TLB. Этот модуль необходимо подключить к проекту, чтобы получить доступ к работе с регулярными выражениями в Delphi. Подключаем модуль и переходим ко второму шагу – изучению сайта с которого будем “вытягивать” информацию по домену.

    2. Изучаем сайт на предмет наличия и расположения информации

    Итак, для решения поставленной задачи нам необходимо знать только одно – дату регистрации домена.

    Я не стал долго копаться в поисках whois-сервера и выбрал в качестве цели  who.is – довольно удобный сервис, который, в случае необходимости, можно будет использовать для решения других задач при работе с доменными именами.

    Теперь проверим как выглядит страница с необходимой информацией. Забиваем в строку поиска любой домен, например webdelphi.ru и жмем “Who is Search”. В итоге получаем страничку следующего содержания:

    whois_webdelphiКрасным цветом выделена необходимая нам строка (рисунок кликабельный) – дата создания домена. Казалось бы все просто – нашел строку, вытащил дату и дело в шляпе. Но, если б все было так просто – был бы рай :) Попробуйте теперь найти информацию, например по домену yahoo.com и вид странички с информацией будет уже другой. Например вместо строки created будет Creation Date, а, если заглянуть в исходный код, то для первого случая (webdelphi.ru) исходный код строки будет совершенно иной нежели для второго – обратите внимание на то, как прописаны пробелы.

    Соответственно, для того, чтобы парсить подобные страницы в поисках даты создания домена необходимо либо иметь под рукой два регулярных выражения – каждое для своего случая (что весьма не рационально и не факт, что сработает), либо создать одно более-менее универсальное, которое подойдет для всех случаев. Я написал такое регулярное выражение, которое и представляю на Ваше обозрение.

    3. Регулярное выражение для поиска даты создания домена

    Итак, у меня получилось вот такое регулярное выражение:

    '^CD+(d{4}.d{2}.d{2})|Cw{7,8}sw{4}:D+(d{4}-d{2}-d{2})'

    Регулярное выражение состоит из двух частей:

    Первая часть – для поиска даты создания домена в подстроке, содержащей “created”:

    '^CD+(d{4}.d{2}.d{2})'

    т.е. ищется подстрока, начинающаяся с символа С, затем в строке должно содержаться 1 или более символов (не цифр) и непосредственно сама дата создания домена в формате yyyy.mm.dd причем в регулярном выражении указано явно, что разделителем выступает символ “.”

    Вторая часть регулярного выражения ищет даты в строках, содержащих подстроку “Creation Date”:

    'Cw{7,8}sw{4}:D+(d{4}-d{2}-d{2})'

    Здесь опять же первым символом должен быть символ “С”, далее указано, что в строке должны идти подряд 7 или 8 букв, потом простой пробел, ещё 4 буквы, двоеточие, 1 или несколько символов и сама дата в формате yyyy-mm-dd Разделитель опять же указан явно.

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

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

    4. Пишем приложение для определения возраста домена

    Приложение наше будет считать возраст домена в днях и выглядеть довольно простенько:

    prilogenieИмя домена задается без http:// как это и должно быть. После нажатия на кнопку “Проверить” будем выписывать в label’ы дату регистрации и возраст домена. Расположите необходимые компоненты на форме и приступим к программированию.

    По сути, для работы программы необходимо описать всего одно событие – клик по кнопке. Процедура выглядит следующим образом:

    procedure TForm2.Button1Click(Sender: TObject);
    var
      Text: TStringList;
      Reg: TRegExp;
      mc: MatchCollection;
      m: Match;
      sm: SubMatches;
      i, j: Integer;
      D: TDateTime;
    begin
      URLDownloadToFile(nil, PChar(Format(site,[Edit1.Text])), PChar
      (ExtractFilePath(Application.ExeName) + 'Text.txt'), 0, nil);
      Text := TStringList.Create;
      Text.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Text.txt');
      Reg := TRegExp.Create(Self);
      try
        Reg.Pattern :=Pattern;
        Reg.IgnoreCase:=true;
        Reg.Global:=true;
        Reg.Multiline:=true;
        mc:=Reg.Execute(Text.Text) as MatchCollection;
        if mc.Count > 0 then
          begin
            m:=mc[0] as Match;
            sm:=m.SubMatches as SubMatches;
            for j := 0 to sm.Count - 1 do
              begin
                if length(VarToStr(sm[j])) > 0 then
                  begin
                    Label5.Caption := VarToStr(sm[j]);
                    D:=VarToDateTime(sm[j]);
                    Label7.Caption := IntToStr(DaysBetween(Now,D))+' дней';
                  end;
              end;
          end
      else
        begin
          label5.Caption:='не определена';
          label7.Caption:='не определен'
        end;
      finally
        m:=nil;
        sm:=nil;
        mc:=nil;
        Reg.Free;
      end;
    end;

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

    URLDownloadToFile(nil, PChar(Format(site,[Edit1.Text])), PChar
    (ExtractFilePath(Application.ExeName) + 'Text.txt'), 0, nil);
    Text := TStringList.Create;
    Text.LoadFromFile(ExtractFilePath(Application.ExeName) + 'Text.txt');

    Причём функция URLDownloadToFile содержится в модуля urlmon, который необходимо подключить в uses.

    При задании URL’а для скачивания я использовал константу:

    site = 'http://www.who.is/whois/%s';

    Далее начинается работа непосредственно с регулярными выражениями:

    1. Создаем объект TRegExp и задаем ему свойства

    Reg.Pattern :=Pattern;
    Reg.IgnoreCase:=true;
    Reg.Global:=true;
    Reg.Multiline:=true;

    Pattern – наше регулярное выражение. IgnoreCase – игнорируем регистр символов при поиске. Global – пытаться найти все возможные соответствия в строке. Multiline – поддерживать многострочный режим.

    2. Ищем все соответствия в тексте

    mc:=Reg.Execute(Text.Text) as MatchCollection;

    то есть все найденные соответвия в строке Text.text, заданные в Pattern, возвращаем в коллекцию MatchCollection.

    Ну, и далее, если соответствие было найдено (а в идеале оно должно быть только одно), то просматриваем коллекцию субсответсвий, т.е. тех частей строки, которые в Pattern обозначены круглыми скобками. Это и будет наша дата регистрации домена.

    3. Как только нашли дату, определяем возраст домена в днях, для этого используем функцию DaysBetween из модуля DateUtils.

    4. Выдаем информацию пользователю.

    Работа программы завершена. Вид программы после завершения работы представлен на рисунке:

    prilogenie2Как видите, мой блог ещё совсем маленький – всего 75 дней от роду :)

    Кстати, при тестировании приложения оказалось, что домен google.com всего на два дня моложе домена yandex.ru…а я почему то всегда считал, что google намного старше нашего Яшки.

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

    Age of domain(382.22 KB)

    Мой блог находят по следующим фразам

    Для того, чтобы быть в курсе последних обновлений блога WebDelphi.ru Вы можете:
    Подписаться на RSS
    Подписаться на рассылку по e-mail
    Подписаться на RSS-трубу Delphi и получать новости сразу пяти блогов по программированию на Delphi
    Закладки:
    • Digg
    • del.icio.us
    • Facebook
    • Google Bookmarks
    • RSS
    • FriendFeed
    • LinkedIn
    • Live
    • Twitter

    Похожие записи:

    1. Компонент Delphi 2010 для определения даты регистрации и возраста домена.
    2. Определение тИЦ Яндекс. Компонент Delphi 2010.
    3. Простейший компонент Delphi 2010 для парсинга выдачи Яндекс.

    Автор Vlad в 3:35 pm

    Метки: ,

9 Comments

WP_Cloudy
  • progg.ru пишет:

    Определение возраста домена. RegExp в Delphi 2010. | Delphi в Internet…

    Thank you for submitting this cool story – Trackback from progg.ru…

  • Masha пишет:

    Привет) Регулярка правильная) Понятно, что можно записать ее разными способами, у каждого разработчика, как мне кажется, складывается со временем свой собственный стиль написания регулярок — такой, который ему удобен и более прост… Например, я бы ту же самую дату искала бы другой регуляркой:
    (?:created|creation date):.*?(\d{4}[\.-]{1}\d{2}[\.-]{1}\d{2})
    То есть в самом начале — либо created, либо creation date. Потом двоеточие, потом сколько-то каких-то символов, потом сама дата: 4 цифры года, разделитель (точка либо дефис), 2 цифры месяца, разделитель, 2 цифры дня :) После разделителя можно не указывать {1}, так как исключений не будет, я указала просто для наглядности)) Зная, что формат даты задан четко, можно было еще упростить выражение, но это уже не существенно )
    Кстати, а почему за “c” в слове “Creation” может идти 7 или 8 букв? Я насчитала четко 7 ) Или там может быть другое слово? Когда вариантов мало и слова короткие, я предпочитаю упрощать и не писать регулярку для каждого слова в отдельности, а просто перечислить варианты, какие могут встретиться.
    Удачи в освоении регулярок) Крайне полезное дело))

  • Vlad пишет:

    Приветик, Маша) Спасибо за развернутый ответ. На самом деле – это было самое первое мое регулярное выражение…видимо ещё не совсем постарел – что-то получилось. По поводу 7 или 8 букв, когда писал регулярку толком не понимал как считается совпадение вместе с “С” или без поэтому сделал такой “запас” :) Теперь начинаю по-тихоньку осваиваться, разбираться. Спасибо за свой вариант регулярки, очень пригодится мне в дальнейшем. Удачи с RSSAdder’ом ;)

  • RКостя пишет:

    Развернутый отзыв не оставлю, но статья интересная. буду следить!
    Вам спасибо!

  • Полка пишет:

    Отличный сайт,интересно здесь

  • webv пишет:

    Спасибо, программка очень выручила в важном деле.

  • Vlad пишет:

    Не за что) Всегда рад помочь, особенно в важных делах

  • dimio пишет:

    Точку не забывайте экранировать (\.), иначе возможны неожиданности. Хотя сам символ точки и попадает  под действие метасимвола “точка”, под него и другие символы тоже попадут. Тогда если в коде страницы встретится какой-то ключ например (1234&12>21) – он под регулярку с неэкранированной точкой тоже попадет. В общем подобные вещи лучше предусмотреть сразу, чем потом ломать голову над непонятным выводом.

  • Vlad пишет:

    Спасибо за совет. Буду иметь в виду. Кстати, сейчас изучаю регулярки в Lazarus – немного необычно сделали, но тоже интересно. Как более менее разберусь попробую сравнить работу.

Ваш ответ

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

Пожалуйста, заключайте программный код в теги [code][/code].


Protected by Copyscape Duplicate Content Detector