уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

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

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

В Delphi XE появилась собственная библиотека для работы с регулярными выражениями. Более подробную информацию о библиотеке можно узнать здесь.

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 намного старше нашего Яшки.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
12 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Masha
30/09/2009 08:33

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

Полка
Полка
06/10/2009 11:55

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

dimio
04/12/2009 16:08

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

LaStick
LaStick
26/08/2010 15:01

А вот не понял, что, все слэши в регулярных выражениях послетали или так оно и должно быть? А то мне что-то кажется что я с ума схожу. :)

Андрей
Андрей
22/09/2010 00:48

У меня ругается Delphi 2010 на TRegExp. Только если ставить просто RegExp. Заглянул в модуль регулярок и увидел там следующее:

RegExp = IRegExp2;
Match = IMatch2;
MatchCollection = IMatchCollection2;
SubMatches = ISubMatches;

В общем, при импорте заметно, что создаются классы через T, но реально это не работает почему-то.

Александр
23/12/2010 21:43

Добавь в uses VBScript_RegExp_55_TLB

Sad Spirit
Sad Spirit
26/02/2011 03:00

http://www.regexbuddy.com/
C этой софтиной написание регулярок превращается в лехкое и непринужденное занятие.
Крайне рекомендую.

trackback

[…] компонент Delphi 2010, для работы со Шкурами.    Определение возраста домена. RegExp в Delphi 2010. […]