Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Работа с DIRegEx -библиотека регулярных выражений для Delphi

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
DIRegEx
 
Не найдётся ли у кого более-менее простых примеров для работы с этими компонентами.
Например, есть страница HTML.  
Нужно отпарсить её, и в цикле получить все ссылки.
Указать начальные данные несложно:
 
регулярное выражение
  DIPerlRegEx1.MatchPattern := '.......';
 
текст, в котором будем искать
  DIPerlRegEx1.SetSubjectStr();
 
А вот как правильно получить результат и выполнить цикл по всем совпадениям?

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 01:47 26-09-2009 | Исправлено: X11, 01:55 26-09-2009
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Как правильно узнать количество совпадений?

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 20:16 28-09-2009
KF121



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
   Regex:=TDIPerlRegEx.Create(nil);
    Regex.SetSubjectStr(Strings.Text);
    Regex.Options:=[poCaptureSubstrings];
    Regex.CompileOptions:=[coCaseLess, coMultiline, coDotAll];
 
    {Functions search}
    i:=0;
    if cFunc<>'' then begin
      Regex.MatchPattern:=cFunc;
      if not regex.CompileMatchPattern then StatusBar.Panels[8].Text:='FuncDetect error ' + IntToStr(RegEx.ErrorCode) + ': ' + RegEx.ErrorMessage + ' (at ' + IntToStr(RegEx.ErrorOffset + 1) + ').'
      else if Regex.Match(0)>=0 then begin
        repeat
          if Attrib then edit.GetHighlighterAttriAtRowCol(edit.CharIndexToRowCol(Regex.SubStrFirstCharPos(0)), s, attri);
          if assigned(attri) then begin
            attri.Name:=LowerCase(attri.Name);
            if (pos('string',attri.Name)=0)and
               (pos('comment',attri.Name)=0)and
               (pos('remark',attri.Name)=0)
            then if AddFunc(PfmMain, Node, regex, Strings, Attrib, fn) then inc(i);
          end
          else if AddFunc(PfmMain, Node, regex, Strings, Attrib, fn) then inc(i);
        until (Regex.MatchNext<0)or(i=1024)or(KeyTime=0);
        if i>=1024 then begin
          StatusBar.Panels[8].Text:='Too many functions found! First 1024 parsed.';
          MessageBeep(MB_ICONEXCLAMATION);
        end
      end;
      if cSortTree then Node.AlphaSort(true);
      Node.Expanded:=FuncExp;
    end;
 
ну вроде этого что-то.

Всего записей: 170 | Зарегистр. 24-05-2006 | Отправлено: 23:25 29-09-2009
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
DiRegEx 4.3, D2007.
 
Парсинг HTML.
Вот регулярка: (?i)(http:.*?>Следующая)
Исходный текст отсюда: irr.ks.ua/Default.aspx?Rubric=2&SubRubric=38
Когда тестирую выражение в DiRegEx Workbench, то всё прекрасно. Эта программа находит и возвращает одну нужную строку (ссылку на след. страницу).
Если в регулярку добавить модификатор s, то Workbench выводит в результат сразу несколько строк (?si)(http:.*?>Следующая)
 
А вот, когда я в своей программе выполняю парсинг, то ВСЕГДА rexp.MatchedStr возвращает не одну нужную строку, а многострочный текст: от самого начала текста (от первого http) и до слова "Следующая".
 
Вот функция

Код:
 
function ParseByDI(InputString: string; MatchPattern: string): TParsedArray;
var
  rexp:       TDIRegEx;
  tempArray:  TParsedArray;
  count, i:   Integer;
begin
  rexp := TDIPerlRegEx.Create(nil);
  try
    rexp.SetSubjectStr(InputString);
    rexp.MatchPattern := MatchPattern;
 
 
 
//даже при явном отключении многострочности в результате появляется не 1, а много строк
    rexp.CompileOptions := rexp.CompileOptions - [coDotAll];
 
 
 
    if rexp.Match(0) < 0 then
      begin
        //если нет совпадений
        SetLength(TempArray, 1);
        tempArray[count].Ind   := 0;
        tempArray[count].Len   := 0;
        tempArray[count].Match := '';
        exit;
      end;
 
    count := 0;
    repeat// пока есть совпадению
      SetLength(TempArray, count+1);
      tempArray[count].Ind   := count;
      tempArray[count].Len   := Length(rexp.MatchedStr);
      tempArray[count].Match := rexp.MatchedStr;
 
      Inc(count);
    until rexp.MatchNext < 0;
    Result := TempArray;
  finally
    FreeAndNil(rexp);
  end;
end;
 

 
Что не так? Что ещё я забыл?  
 
Добавлено:
KF121, спасибо за пример

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 00:37 30-09-2009
kruzen33

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
куда я впёрся...

Всего записей: 2 | Зарегистр. 27-09-2009 | Отправлено: 10:13 02-10-2009
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Есть строка
. ул. Дорофеева, малосемейка, 5/9, 32/18/6, после ремонта, лифт не работает, новая металлическая дверь, линолеум, кафель, батареи, вода постоянноЦена: 20500 $. Тел:5645456456456, Сайт: <atarget="_blank" href="http://www.info-broker.ks.uawww.info-broker.ks.ua, . office @ info-broker ks ua
 
вот образец: Сайт.*?,
 
Вот функция замены:

Код:
 
function ReplaseByDi2(const InputStr: String; const MatchPattern: String;const NewString: String): String;
var
  RE: TDIPerlRegEx;
  AOptions: TDIRegexCompileOptions;
begin
//RegExReplace('Apple', '\bapple\b', 'orange', [coCaseLess]);
//http://bbs.cnsoftware.cn/thread-217-1-1.html
 
  RE := TDIPerlRegEx.Create(nil);
  try
    RE.SetSubjectStr(InputStr);
    AOptions := {[coCaseLess];}[coCaseLess, coMultiline, coDotAll];
    RE.CompileOptions := AOptions;
 
    if not RE.CompileMatchPatternStr(MatchPattern) then showMessage('Ошибка RE.CompileMatchPatternStr');
 
    RE.FormatPattern := NewString;
 
 
 
//здесь всегда 0
 
    if RE.Replace2(Result) = 0 then
      Result := InputStr;
 
 
 
 
  finally
    RE.Free;
  end;
end;
 

 
Хотя в демке Workbench замена работает. Что не так?

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 17:33 14-01-2010
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
X11
Цитата:
Хотя в демке Workbench замена работает.

1. А в демке такие-же опции установлены ?
2. Какая версия Delphi и DIRegEx ?
Потому как:

Цитата:
DIRegEx 5.1.1 – 29 Oct 2009
Change published TDIRegEx.MatchPattern property back to AnsiString. This was unfortunately required type to fix a Delphi 2009 / 2010 RawByteString streaming problem.
Add new public TDIRegEx.MatchPatternRaw: RawByteString property to allow Unicode Delphis to set the MatchPattern without automatic codepage conversion. This is now the recommended MatchPattern runtime property.
и
Цитата:
DIRegEx 5.0.1 – 31 Jan 2009
Work around an unexpected Delphi 2009 automatic numeric AnsiChar Unicode conversion in DIUtils.pas which caused an error when compiled on a Windows OS set to a non-European (Asian, Cyrillic, etc.) codepage.
3. И если это "стянутая" страница, может лучше использовать DIHtmlParser (в обменнике есть) ?

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 03:37 15-01-2010 | Исправлено: data man, 04:29 15-01-2010
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
1. А в демке такие-же опции установлены ?  

Да.
 

Цитата:
2. Какая версия Delphi и DIRegEx ?  

Д2070 + DiRegEx 4.3
 
Добавлено:
Я вот что сделал, обрамил выражение скобками, вот так:  (Сайт.*?,)
И парсинг заработал. Хотя  workbench работает и без скобок.
 
data man, ты случайно не знаешь, можно ли параметры модификации в выражении? Типа так первое выражение в скобках):
(?msr)(<td><span.*?</span></td>)

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 10:17 15-01-2010
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
X11
 
Не совсем понял про какие параметры речь, и в каком выражении.
Если в выражении замены, то нет - нельзя.
Лучше так: что требуется ? Замена ссылок на что-то ?
 

Цитата:
Д2070

А где такую скачать можно ?

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 11:07 15-01-2010
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Не совсем понял про какие параметры речь, и в каком выражении.  

Ключи модификации, или как они правильно называются. Это m, i, r, s.
 
 

Цитата:
Лучше так: что требуется ? Замена ссылок на что-то ?  

Требуется замена текста. А правильнее - удаление лишнего текста (мусора) из текста объявления.
Есть парсер сайтов. Нужно выдёргивать тексты объявлений.
 
Добавлено:

Цитата:
А где такую скачать можно ?

Лет через 60 скачаем ))))))
 
У меня Д2007


----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 11:20 15-01-2010
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
X11
Модификаторы, да, можно. И ставить минус перед ними для инвертирования их значения.
 

Цитата:
Нужно выдёргивать тексты объявлений.

IMHO, для этого DIHtmlParser лучше всего подходит.
И тэги правильно обрабатывает, плагины есть и для таблиц и для извлечения линков.
Да и работает очень быстро.
В общем рекомендую.

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 12:13 15-01-2010
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
А есть ещё DITidy, что это за..

----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 12:36 15-01-2010
data man



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
X11
Это обёртка над популярной Сишной libtidy, парсит XML, HTML и XHTML.
Не OOP - только функции и процедуры.
Вот такой пример извлечения ссылок из файла Подробнее...

----------
Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
Кекс. Антибиотики. Ламбада.

Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 12:50 15-01-2010 | Исправлено: data man, 12:51 15-01-2010
X11



Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Странно себя ведёт эта библиотека со знаком номера №
 
Вот исходный текст:

Цитата:
04.01.2012 № 176853, Москва ,

 
Вот выражение:  

Код:
\d[\d() ]{6,}

 
регулярка находит:

Цитата:
2012 № 176853

 
Разве это правильно?
 


----------
/не мы такие, жизнь такая/

Всего записей: 3253 | Зарегистр. 24-11-2005 | Отправлено: 15:22 06-01-2012
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Работа с DIRegEx -библиотека регулярных выражений для Delphi


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru