Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.07.2011, 01:22   #1
Lauri
Форумчанин
 
Регистрация: 01.04.2010
Сообщений: 171
По умолчанию Упрощения парсинга текста

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

Есть текст такого типа
Код HTML:
| 69.168.44.98:5060     | unknown                                                      |             |
| 152.179.24.182:54814  | Cisco-SIPGateway/IOS-12.x                                    |             |
| 63.117.214.69:5060    | unknown                                                      |             |
| 63.119.12.250:5060    | ARRIS-TM602G release v.6.1.77T.SIP SN/001DCD7C2E08           |             |
| 63.65.167.174:5060    | unknown                                                      |             |
| 69.168.44.212:5060    | unknown                                                      |             |
| 63.119.51.249:5060    | unknown                                                      |             |
| 69.168.41.51:5060     | unknown                                                      |             |
| 63.108.178.14:5060    | Asterisk PBX                                                 |             |
Мне нужно скопировать АЙПИ из тех строк, где есть аббревиатура "PBX"

Реализую я это такой процедурой
Код:
var
  Form1: TForm1;
    a,b,i,ii:integer;
    S:STRING;


function cpos(sub,s:string):integer;
begin
   result:=0;
   while pos(sub,s)>0 do begin
      inc(result);
      s:=copy(s,pos(sub,s)+length(sub),length(s));
   end;
end;


procedure TForm1.Button1Click(Sender: TObject);
   var
   bb:string;
   aq:integer;

   s:string;
begin
b:=10;
a:=9;
ProgressBar1.Position:=0;
progressbar1.Min:=0;
progressbar1.max:=memo1.lines.count;
for i:=0 to memo1.Lines.count do begin
application.ProcessMessages;
if a>b then break;
if cpos('PBX',memo1.Lines[0])>0 then
 memo2.lines.add(Copy (Form1.Memo1.Lines[0], Pos(' ', Form1.Memo1.Lines[0]) + 1, Pos(':', Form1.Memo1.Lines[0]) - Pos(' ', Form1.Memo1.Lines[0]) - 1));
 memo1.Lines.delete(0);
ProgressBar1.Position := ProgressBar1.Position + 1;
end;
 memo2.Lines.delete(0);
end;
Но заказчика не устраивает что такой парсинг грузит его процессор на 100% ((
Как быть?( помогите найти выход из ситуации. Что поменять в коде?

Последний раз редактировалось Lauri; 16.07.2011 в 01:33.
Lauri вне форума Ответить с цитированием
Старый 16.07.2011, 01:35   #2
Ghost of Night
Форумчанин
 
Аватар для Ghost of Night
 
Регистрация: 08.08.2010
Сообщений: 371
По умолчанию

Зачем здесь переменные a,b. К тому же, МЕМО можно заменить на TStringList
Хакинг - не преступление, а способ выживания.
Ghost of Night вне форума Ответить с цитированием
Старый 16.07.2011, 01:39   #3
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> Как быть?

Добавить вызов Sleep(1) перед или после application.ProcessMessages();

(ЗЫ. Это будет не "упрощение", а замедление парсинга, но раз заказчик сам этого хочет, пусть получает)
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 16.07.2011 в 01:42.
veniside вне форума Ответить с цитированием
Старый 16.07.2011, 01:43   #4
Ghost of Night
Форумчанин
 
Аватар для Ghost of Night
 
Регистрация: 08.08.2010
Сообщений: 371
По умолчанию

По моему проще было бы написать
Код:
var
 str: TStringList;
begin
...
if pos('PBX', Str.Strings[i]) >0 then
//вместо
if cpos('PBX',memo1.Lines[0])>0 then
2-е Если текстофый файл небольшой, то ProgressBar можно убрать, это сократит код.
В данном примере
Цитата:
if a>b then break;
Всегда ложно.
И как я уже говорил, Выводить в МЕМО только результат. А данные из TStringList читать, поместив в переменную обрабатываемую строку, а после обработки если она подходит то её в МЕМО выводить.
Хакинг - не преступление, а способ выживания.
Ghost of Night вне форума Ответить с цитированием
Старый 16.07.2011, 01:46   #5
Ghost of Night
Форумчанин
 
Аватар для Ghost of Night
 
Регистрация: 08.08.2010
Сообщений: 371
По умолчанию

veniside Парсинг нужно не замедлить а оптимизировать. Хотя ваш вариант тоже приемлем, но для небольших файлов.
Хакинг - не преступление, а способ выживания.
Ghost of Night вне форума Ответить с цитированием
Старый 16.07.2011, 01:46   #6
Lauri
Форумчанин
 
Регистрация: 01.04.2010
Сообщений: 171
По умолчанию

Цитата:
Сообщение от Ghost of Night Посмотреть сообщение
Зачем здесь переменные a,b. К тому же, МЕМО можно заменить на TStringList
По значениям a,b я останавливаю или начинаю процедуру. Извращение, но мне удобно

Цитата:
Сообщение от veniside Посмотреть сообщение
> Как быть?

Добавить вызов Sleep(1) перед или после application.ProcessMessages();

(ЗЫ. Это будет не "упрощение", а замедление парсинга, но раз заказчик сам этого хочет, пусть получает)
Спасибо, помогает. На этот вопрос я получил ответ. Но хотелось бы не терять скорость, ведь работаю с файлами по 9 мб...( Может как то предварительно порезать файл на части и грузить по очереди каждую часть?
Lauri вне форума Ответить с цитированием
Старый 16.07.2011, 01:47   #7
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

Сколько ни мудри, этот цикл без Sleep() или подобного всегда будет грузить одноядерный проц на 100%, и это правильно, так и должно быть, заказчик просто тупит.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 16.07.2011, 09:07   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

1) КАТЕГОРИЧЕСКИ не рекомендую использовать Memo для обработки текста!
Фактически, Вам нужен Lines - так он типа TSTringList
вот создавайте объект TStringList и работайте с ним.
Код:
var TS : TStringList; 
begin
   TS := TStringList.Create;
   TS.LoadFromFile('Имя файла');
   обработка...
   MemoXX.Lines.Text := TS.Text;
   FreeAndNil(TS)
end;
Ну, очевидно, что если нужно для помещения результатов ещё один объект, то нужно не использовать Memo2, создать ещё один TStringList!

2) в 99% задач парсинга НЕ ТРЕБУЕТСЯ удалять строчки из текста. А это КРАЙНЕ тормозная операция! ЗАчем Вы удаляете строки из Memo1 ?!
попробуйте такой код. О результатах отпишитесь:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  i: integer;
  TS, TSRes: TStringList;
begin
  b := 10;
  a := 9;
  TS := TStringList.Create;
  TS.Text := Memo1.Lines.Text;
  ProgressBar1.Position := 0;
  progressbar1.Min := 0;
  progressbar1.max := TS.count;
  TSRes := TStringList.Create;
  try
    for i := 0 to TS.count - 1 do begin
      application.ProcessMessages;
      if a > b then break;
      if pos('PBX', AnsiUpperCase(TS.Strings[i])) > 0 then
        TSRes.add(Copy(TS.strings[i], Pos(' ', TS.strings[i]) + 1, 
           Pos(':',TS.strings[i]) - Pos(' ', TS.strings[i]) - 1));
      ProgressBar1.Position := ProgressBar1.Position + 1;
    end;
    memo2.Lines.Text := TSRes.Text;
  finally
    FreeAndNil(TS);
    FreeAndNil(TSRes);
  end;
end;

Последний раз редактировалось Serge_Bliznykov; 16.07.2011 в 09:19.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 16.07.2011, 12:11   #9
Lauri
Форумчанин
 
Регистрация: 01.04.2010
Сообщений: 171
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
1) КАТЕГОРИЧЕСКИ не рекомендую использовать Memo для обработки текста!
Фактически, Вам нужен Lines - так он типа TSTringList
вот создавайте объект TStringList и работайте с ним.
Код:
var TS : TStringList; 
begin
   TS := TStringList.Create;
   TS.LoadFromFile('Имя файла');
   обработка...
   MemoXX.Lines.Text := TS.Text;
   FreeAndNil(TS)
end;
Ну, очевидно, что если нужно для помещения результатов ещё один объект, то нужно не использовать Memo2, создать ещё один TStringList!

2) в 99% задач парсинга НЕ ТРЕБУЕТСЯ удалять строчки из текста. А это КРАЙНЕ тормозная операция! ЗАчем Вы удаляете строки из Memo1 ?!
попробуйте такой код. О результатах отпишитесь:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  s: string;
  i: integer;
  TS, TSRes: TStringList;
begin
  b := 10;
  a := 9;
  TS := TStringList.Create;
  TS.Text := Memo1.Lines.Text;
  ProgressBar1.Position := 0;
  progressbar1.Min := 0;
  progressbar1.max := TS.count;
  TSRes := TStringList.Create;
  try
    for i := 0 to TS.count - 1 do begin
      application.ProcessMessages;
      if a > b then break;
      if pos('PBX', AnsiUpperCase(TS.Strings[i])) > 0 then
        TSRes.add(Copy(TS.strings[i], Pos(' ', TS.strings[i]) + 1, 
           Pos(':',TS.strings[i]) - Pos(' ', TS.strings[i]) - 1));
      ProgressBar1.Position := ProgressBar1.Position + 1;
    end;
    memo2.Lines.Text := TSRes.Text;
  finally
    FreeAndNil(TS);
    FreeAndNil(TSRes);
  end;
end;
Огромное спасибо! Всё работает точно как нужно! Не нагружает процессор, и скорость обработки очень высока.

Вывод :
Работать со стринглист, в мемо выводить ТОЛЬКО результат.
Правильно понимаю?
Lauri вне форума Ответить с цитированием
Старый 16.07.2011, 12:40   #10
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

ну да, компоненты это средство ввода/вывода информации, но не для прямой обработки.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не выводится текст парсинга bulldog5293 Работа с сетью в Delphi 0 30.04.2011 18:26
Банальное равенство парсинга bulldog5293 Общие вопросы Delphi 2 29.03.2011 00:29
ВАРИАНТЫ ПАРСИНГА Vova777 Общие вопросы Delphi 2 04.09.2010 23:51
Мелкая ошибка парсинга Legenda PHP 4 02.10.2008 17:52
пример парсинга Stanislav Общие вопросы Delphi 4 14.01.2008 03:48