Авторизация

Логин: Пароль:
Регистрация Забыли свой пароль?

Получить текст между двумя словами

Страницы: 1
Получить текст между двумя словами
Всем привет.
Столкнулся пару дней назад с проблемой и до сих пор не могу её решить. В общем, суть задачи в том чтобы получить из текста вида
Цитата
НАЧАЛО_ТЕКСТ КОТОРЫЙ НУЖЕН_КОНЕЦ_ЕЩЕ КАКОЙ-ТО ТЕКСТ_НАЧАЛО_ТЕКСТ КОТОРЫЙ НУЖЕН_КОНЕЦ
текст между словами начало и конец.
Алгоритм здесь достаточно простейший. Нужно сначала найти позицию в тексте со словом НАЧАЛО и получить весь текст полсле нее. Потом Получить текст до слова КОНЕЦ.
Алгоритм я себе и сам представляю. Но как это реализовать? Признаюсь у меня мало опыта в работе со строками.
Вот функция получения строки после определенного текста
Код
Function After ( Src:string ; Var S:string ) : string ;
Var
  F : Word ;
begin
  F := POS (Src,S) ;
  if F=0 then
    After := ''
  else
    After := COPY(S,F+length(src),length(s)) ;
end ;
А вот эта функция получения текст до заданного
Код
Function Before ( Src:string ; Var S:string ) : string ;
Var
  F : Word ;
begin
  F := POS (Src,S) ;
  if F=0 then
    Before := S
  else
    Before := COPY(S,1,F-1) ;
end;
Изменено: Алексей Смирнов - 23.05.2010 21:53:08
Чего-то попробовал я обе эти функции и ожидаемого результата не получил. Попробую еще завтра.
Попробуйте еще вот такую функцию
Код
Procedure IsolateText( Const S: String; Tag1, Tag2: String; list:TStrings );
  Var
    pScan, pEnd, pTag1, pTag2: PChar;
    foundText: String;
    searchtext: String;
  Begin
    searchtext := Uppercase(S);
    Tag1:= Uppercase( Tag1 );
    Tag2:= Uppercase( Tag2 );
    pTag1:= PChar(Tag1);
    pTag2:= PChar(Tag2);
    pScan:= PChar(searchtext);
    Repeat
      pScan:= StrPos( pScan, pTag1 );
      If pScan <> Nil Then Begin
        Inc(pScan, Length( Tag1 ));
        pEnd := StrPos( pScan, pTag2 );
        If pEnd <> Nil Then Begin
          SetString( foundText,
                     Pchar(S) + (pScan- PChar(searchtext) ),
                     pEnd - pScan );
          list.Add( foundText );
          pScan := pEnd + Length(tag2);
        End
        Else
          pScan := Nil;
      End;
    Until pScan = Nil;
  End;
Я тут в соседней ветке давал пример кода, может быть, вам поможет:
Код
procedure TForm1.FormCreate(Sender: TObject);
var x:TStringList;
begin

x:=TStringList.create;
  x.text:=stringReplace('часть1|часть2|часть3','|',#13#10,[rfReplaceAll]);
  showmessage(x[0]);
  showmessage(x[1]);
  showmessage(x[2]);
  x.free;
end;

end.

В качестве разделителей надо взять НАЧАЛО и КОНЕЦ, я думаю.
Accende lumen sensibus, infude ainorem corbidus!
Виктор, спасибо, но это тоже не подходит, потому что мне нужно получить несколько фраз из одной строки,а это функция возвращает только одну.
motorway11
Спасибо, но Ваш код мне тоже не подходит, так как он просто делит строку но в ней также остаются нужные и не нужные участки.
Игорь Васильев,
Вам нужна какая-нибудь библиотечка, реализующая работу регулярных выражений.
Посмотрите здесь , может это то?
http://rpdn.ru/forum/18/51/
Но ведь можно же потом применить его к результату первого этапа smile;) Я всегда так делаю, когда надо что-то вырезать. Сначала обрезаю большой кусок, потом из него уже края и т.п. Должно получиться!
Общий принцип такой: режем строку по разделителям "Начало", а потом в цикле для каждой получившейся части режем ее по разделителю "конец" и берем самую первую часть
Изменено: motorway11 - 24.05.2010 18:27:56
Accende lumen sensibus, infude ainorem corbidus!
Написал пример небольшой, не уверен за точную работоспособность, но идея такая:

Код
procedure TForm1.FormCreate(Sender: TObject);
var x,y:TStringList;
begin

x:=TStringList.create;
  x.text:=stringReplace('ваш текст','конец',#13#10,[rfReplaceAll]);
  y.text:=stringReplace(x[0],'начало',#13#10,[rfReplaceAll]);
showmessage(y[0]);
  x.free;
  y.free;
end;
end.


После этого в y[0] должно показаться первое вхождение нужного текста
Изменено: motorway11 - 24.05.2010 19:07:57
Accende lumen sensibus, infude ainorem corbidus!
Дмитрий, спасибо, я уже думал о регулярных выражениях. Более сложной для понимания вещи я еще не встречал, поэтому и решил обойтись пока простыми функциями.
Цитата
Игорь Васильев пишет:
Дмитрий, спасибо, я уже думал о регулярных выражениях. Более сложной для понимания вещи я еще не встречал, поэтому и решил обойтись пока простыми функциями.

Я тоже их не люблю и никогда особо в них не разбирался, все делал простыми функциями. А когда они действительно были нужны, просил помощи на форумах - там бывают люди, которые в них понимают. Ну хотя общий принцип мне ясен, но просто обычно синтаксис получается очень запутанный.
Accende lumen sensibus, infude ainorem corbidus!
Цитата
motorway11 пишет:
После этого в y[0] должно показаться первое вхождение нужного текста

Эх, если бы нужно было только первое. Виктор Кузьмин здесь уже предлагал решение дающее точно такой-же результат.
Ну я и говорю - сделайте цикл от 1 до числа элементов в массиве после порезки по слову Начало (либо Конец, что больше нравится). А потом подставляйте туда x[0], x[1] и т.п. Получите все элементы нужные
Accende lumen sensibus, infude ainorem corbidus!
Ну в принципе попробовал, результат есть, но тут выяснилась еще одна сложность. Оказывается строке слово "начало" встречается чаще чем слово "конец". Теперь нужно придумать как взять фразу которая находится между последним началом и концом.
Так вы проверяйте полученную строку на возможность нахождения в ней слово "начало". Если найдено значит обрабатывайте еще раз. Если не найдено, значит вы достигли результата.
По-моему, на примере разбора этой проблемы видна одна важная вещь: мы пробуем писать сами функции для достаточно простых вещей. А ведь должны уже существовать встроенные функции для работы со строками. Или в Дельфи не так всё? Ведь даже для простых операций нужно что-то изобретать. А в языках C# и PHP, например, обычно есть список функций, которые можно использовать. И там это обычно можно сделать за 5 строчек где-то максимум.
Получается, что у программиста много времени теряется на рутинные вещи. И вывод, что для большого проекта нужно искать радикальные способы ускорения производительности smile;)
Accende lumen sensibus, infude ainorem corbidus!
В Delphi на самом деле очень много функций, в том числе и для работы со строками. Многие из них можно найти если ввести в справке "String handling routines". А задача здесь на самом деле нетривиальная.
Может быть, я не совсем понял, но автору темы вроде бы нужно получить несколько частей текста, каждая из которых находится между словами начало и конец? Даже в такой постановке вроде бы довольно легко. По крайней мере на PHP я с помощью встроенных функций разделения строки на части и поиска последнего вхождения подстроки это напишу довольно быстро. Если здесь аналогичные функции, то должно быть той же сложности примерно
Изменено: motorway11 - 24.05.2010 23:49:48
Accende lumen sensibus, infude ainorem corbidus!
Функций для работы со строками, на самом деле, достаточно много, и их достаточно легко найти если запустить поиск по справке со словами "string functions" или что-то аналогичное.
Цитата
Игорь Васильев пишет:
Дмитрий, спасибо, я уже думал о регулярных выражениях. Более сложной для понимания вещи я еще не встречал, поэтому и решил обойтись пока простыми функциями.


В данном случаи выражение будет достаточно простым
Код
/word1(.*)word2/

Пользуйтесь
Изменено: Иван Прокофьев - 25.05.2010 20:18:26
Тогда уж лучше так
Код
/word1(.*?)word2/
Как раз получите последнее вхождение.
Страницы: 1
Читают тему (гостей: 1, пользователей: 0, из них скрытых: 0)