Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Поиск текста


Автор: Rondo 6.7.2006, 22:45
Подскажите как можно найти текст в html документе, между какими то тегами.
Тоесть чтоб например в memo выводилось все что лежит между тегами <body>это должно вывестись в momo </body>
 smile  

Автор: Poseidon 6.7.2006, 23:30
Можно smile

Код
function GetTextInHTML(HTML, TegStart, TegFin: string): string;
var p0, p1: integer;
begin
p0:= pos(TegStart, HTML) + Length(TegStart);
p1:= pos(TegFin, HTML);
Result:= copy(HTML, p0, p1-p0);
end;


procedure TForm1.Button1Click(Sender: TObject);
var
HTMLText: string;
begin
HTMLText:= '<body>это должно вывестись в momo </body>';
Memo1.Text:= GetTextInHTML(HTMLText, '<body>', '</body>')
end;


Писал "на коленке", поэтому можно многое оптимизировать. Но главное - суть - должна быть понятна smile 

Автор: Rondo 6.7.2006, 23:35
Спасибки за такой быстрый ответ, ща проверю! 

Автор: Rondo 6.7.2006, 23:54
Все работате, только после того как найдет 1 тег останавливается

Добавлено @ 00:00 
Как сделать чтоб он все тэги страницы выводил, немогу придумать smile  

Автор: Poseidon 7.7.2006, 00:11
Цитата(Rondo @  6.7.2006,  23:54 Найти цитируемый пост)
Как сделать чтоб он все тэги страницы выводил
 Что это значит? На одной странице может быть до сотни различных тегов. Ты хочешь их все выводить? Или ты хочешь выводить все врагменты текста, каторый заключен  к какой-то один тип тега (как <body> в примере)?
 

Автор: Rondo 7.7.2006, 00:16
Я имел в виду чтоб он все писал мне в memo что находится между <тег>...</тег> body я простн взял для примера smile
Мне надо все фрагменты текста на страницы которые заключены в нужный мне тег  

Автор: Poseidon 7.7.2006, 00:24
Ну так загони функцию в цикл smile

Что-то вроди такого (опять "на коленке")   smile 

Код

function GetTextInHTML(HTML, TegStart, TegFin: string): string;
var
p0, p1: integer;
stop: boolean;
iHTML: string;
begin
Result:= '';
repeat
p0:= pos(TegStart, HTML) + Length(TegStart);
p1:= pos(TegFin, HTML);
Result:= Result + copy(HTML, p0, p1-p0);
iHTML:= copy(HTML, p1+Length(TegFin), Length(HTML)-(p1+Length(TegFin)));
Stop:= (iHTML = HTML);
HTML:= iHTML;
until stop;
end;
  

Автор: Rondo 7.7.2006, 00:27
Poseidon, респект! 

Автор: Yanis 7.7.2006, 09:39
Помоему регулярные выражения сильно упрощаю жизнь. 

Автор: Poseidon 7.7.2006, 16:15
Yanis, если бы я дал пример с TRegExpr, думаю он бы вообще ничего не понял а просто скопировал. А так хоть разберется с основами работы со строками ;) 

Автор: Rondo 10.7.2006, 12:19
Опять же в мемо загружаю текст, и хотелось бы чтоб там осталось только:
Хотелось бы найти что находится между определенными тегами... На этот раз только в первом и последнем найденом теге и поместить найденый текст в отдельную строку smile


M
Girder
Название темы должно отражать ее суть!
 

Автор: Guedda 10.7.2006, 14:19
Допустим, у тебя есть строка: <tag>Превед!</tag>
Чтобы вытащить Превед! Необходимо проделать следующее:
Код

uses
  Masks,...;
function CutText(Str : string) : string;
begin
  if MatchesMask(Str, '<tag>*') then
    Result := copy(Str, 6, (length(Str) - 5) - 6);
end;


Добавлено @ 14:21 
Соответственно, если у тебя тег будет не <tag>, а какой либо другой, там уже будешь варьировать с MatchesMask и с copy (там по символам подберешь...) 

Автор: Mechanic 10.7.2006, 14:21
Цитата(Rondo @  10.7.2006,  12:19 Найти цитируемый пост)
Хотелось бы найти что находится между определенными тегами... 

А чем выделены теги? Если как в html, тогда поможет вот эта функа, что написана специально для разбора html тегов
Код

function GetNextTag(var Src:PChar; const Tag:string): string;
//returns given tag body, moves pointer to the end of tag
var PStart,PEnd: PChar;
begin
    Result := '';
    PStart := AnsiStrPos(Src,PChar('<'+Tag+#0));
    if PStart = nil then
    begin
        Src := StrEnd(Src); Exit;
    end;
    PStart := AnsiStrPos(PStart,PChar('>'+#0))+1; //skip paramesters
    Src := PStart;
    PEnd := AnsiStrPos(Src,PChar('</'+Tag+'>'+#0));
    if PEnd = nil then
    begin
        Src := StrEnd(Src); Exit;
    end;
    Src := PEnd + Length(Tag) + 3; //Tag terminator with brackets
    if PEnd = PStart then exit;
    SetLength(Result,PEnd - PStart);
    StrLCopy(@Result[1],PStart, Length(Result));
end;
 

Автор: Sunr1se 10.7.2006, 14:29
насколько я понял, надо просто вставить текст, находящийся между определенными тегами, в отдельную строку? Тогда вот первое, что пришло в голову (уж извините за такой нехороший код).
Код

function ReplaceText(Tag, Text: string): string;
var
  i: integer;
  FoundedTag: string;
  Bool, Bool2: boolean;
begin
  for i := 1 to Length(Text) do
    if (Text[i] = '<') and not Bool2 then
    begin
      FoundedTag := '';
      FoundedTag := FoundedTag + Text[i];
      Bool := true;
    end
    else if (Text[i] <> '>') and Bool then
      FoundedTag := FoundedTag + Text[i]
    else if (Text[i] = '>') and Bool then
    begin
      FoundedTag := FoundedTag + Text[i];
      Bool := false;
      if FoundedTag = Tag then
        Bool2 := true;
    end
    else if (Text[i] <> '<') and Bool2 then
      Result := Result + Text[i]
    else if (Text[i] = '<') and Bool2 then
    begin
      if StringReplace(Copy(Text, i, Length(Tag) + 1),  '/', '', [rfReplaceAll]) = Tag then
        Bool2 := false;
    end;
end;
 

Добавлено @ 14:31
Пока код писал, вон сколько народу уже откликнулось smile   

Автор: Rondo 10.7.2006, 15:01
Спасибо, ща все проверю smile

Добавлено @ 15:12 
Sunr1se, Неправильно понял, допустим у меня такой код.
Код

    </tr>
    <tr>
        <td class="doc" align="left">2006-07-07 20:02:19</td>
        <td class="doc" style="text-align: right;"> 3 897</td>
        <td class="doc" style="text-align: right;"> 51 212</td>
    </tr>
    <tr>
        <td class="doc" align="left">2006-07-08 17:04:06</td>
        <td class="doc" style="text-align: right;"> 1 796</td>
        <td class="doc" style="text-align: right;"> 802</td>
    </tr>
    <tr>
        <td class="doc" align="left">2006-07-09 17:34:14</td>
        <td class="doc" style="text-align: right;"> 23 917</td>
        <td class="doc" style="text-align: right;"> 530 030</td>
    </tr>
    <tr>
        <td class="doc"><b>Итого:</b></td>
        <td class="doc" style="text-align: right;"><b> 14 156 608</b></td>
        <td class="doc" style="text-align: right;"><b> 210 125 741</b></td>
    </tr>


Мне надо выдернуть из этого кода 14 156 608 и 210 125 741 (они в самом низу smile) и положить каждое это число в отдельную строчку мемо. 

Автор: Sunr1se 10.7.2006, 15:57
Тогда сделай так:
В цикле перебирай строчки, записывая в какую-то переменную номер строки, если в ней есть тег <tr>(ну или какой-то другой). Как только цикл закончится, воспользуйся функцией Mechanic'а, передав в нее эту самую строчку. 

Автор: Rondo 10.7.2006, 16:13
Вообщем перелопатил я этот текст и получилось как и ожидал эти самые 2 числа
Код

 14 156 608 210 125 741


Толкько как разлечить что это 2 числа а не 6 числел, и отправить их на разные строки... И числа то могут быть разные  smile  

Автор: Sunr1se 10.7.2006, 16:15
А ты не мог бы показать, каким образом лопатил текст? smile 

Автор: BUGOR 10.7.2006, 16:18
В данном случае однозначно рулят регулярки. Только в твоём примере первый и последний найденные теги какие? Я так понял надо найти всё, что в пределах тегов td и чтобы это были цифры, если так, то выражение будет выглядеть следующим образом:
(?!(<td.*>(<b>)?)) [0-9 ]+(?=((</b>)?</td>))

Из твоего примера моё выражение выдирает следующее:
 3 897
 51 212
 1 796
 802
 23 917
 530 030
 14 156 608
 210 125 741 

Автор: Rondo 10.7.2006, 16:20
Еще Poseidon довал на днях smile
Код

function GetTextInHTML(HTML, TegStart, TegFin: string): string;//Поиск мужду тэгами
var
  p0, p1: integer;
  stop: boolean;
  Text, iHTML: string;
begin
  Result:= '';
  Text:= HTML;
  repeat
    p0:= pos(TegStart, Text) + Length(TegStart);
    p1:= pos(TegFin, Text);
    Result:= Result + copy(Text, p0, p1-p0);
    iHTML:= copy(Text, p1+Length(TegFin), Length(Text)-(p1+Length(TegFin)));
    Stop:= (iHTML = Text);
    Text:= iHTML;
  until stop;
end;
  

Автор: BUGOR 10.7.2006, 16:20
А, ну и если будешь работать с MatchCollection, то просто бери два последних элемента массива, если же с массивами работать не хочешь, то нужно дорабатывать выражение, чтобы оно выбирало текст между двумя последними тегами td, в принципе это несложно, если надо скажи, попробую составить.

Добавлено @ 16:30 
Rondo, объясни мне зачем писать огромные и тормозные функции, когда это всё красиво и элегантно умещается в одно регулярное выражение? 

Автор: Rondo 10.7.2006, 16:38
Неумею я пока ими пользоватся smile Начинающий кодер. А где про них можно хелп найти или самоучитель? 

Автор: Sunr1se 10.7.2006, 16:41
Так ты передавай в функцию строки по отдельности. тогда будешь получать строку, в которой одно число. Удали из строки пробелы и приведи его к типу integer. 

http://anso.da.ru/ - здесь есть и компонент необходимый, и мануальчик небольшой по регулярным выражениямsmile  

Автор: BUGOR 10.7.2006, 16:51
Rondo, Уже оффтопить начали, ну думаю модеры нас простят. Я учил регулярные выражения по книге:
Фридл Дж. Регулярные выражения (2-е изд.), Питер 2003, 464 с., ISBN 5-272-00331-4
Есть в сети. Прочёл всего-лишь порядка 100 страниц, но при этом спокойно могу составлять довольно сложные регулярки. 

Автор: Лысенак 10.7.2006, 18:37
Код

/<b>(.+?)</b>/g

http://www.regularexpressions.info/ 

Автор: Rondo 10.7.2006, 18:54
Нашел эту книгу, и правда легко )) http://foror.name/upload/regexp.zip 

Автор: Eva_Adamova 3.5.2007, 03:22
Пусть я отвечаю поздно, через полгода, но всё равно хочется сказать спасибо. У меня такая же проблемы была, с разбором таблиц в ХТМЛе, сейчас всё стало более менее ясно!

Добавлено через 3 минуты и 18 секунд
Вышеприведённая ссылка на книгу не работает, вот другая  - http://natahaus.ifolder.ru/551395

Автор: Yanis 3.5.2007, 06:52
Приятно осозновать, что есть люди которые пользуются поиском.
Eva_Adamova,  smile 

Автор: AlManZ 10.5.2007, 21:48
Ну чтоб не создавать новый топик... Книга - да, отличная! А вот теперь еще бы где-нить взять эту библиотеку TRegExpr... ссылки, которые нашел уже не работают :(. Можно и на мыло, буду благодарен.

Автор: iddqd 10.5.2007, 22:28
Да прибудем с тобой гугл.
http://www.regexpstudio.com/

Автор: AlManZ 10.5.2007, 22:38
 smile  Огромное человеческое спасибо!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)