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


Автор: Dima85 20.3.2008, 15:57
Есть:
s: string;

В ней хранится текст до 5500 символов.
Необходимо все символы которые находится в <тут> удалить, вместе с <>. 
Помогите пожалуйста.

Автор: Rrader 20.3.2008, 16:07
Код

Function PreprocessStr(AOrig: String): String;
Var
  NextToken: Char;
  P: Integer;

  Procedure RemoveTag;
  Begin
    Repeat
      NextToken := AOrig[P];    
      Delete(AOrig, P, 1);    
    Until NextToken = '>';
  End;

Begin
  Result := '';
  P := Pos('<', AOrig);
  While P <> 0 Do
  Begin
    RemoveTag;
    P := Pos('<', AOrig);
  End;
  Result := AOrig;
End;

Использование:
Код

ShowMessage(PreprocessStr('1<1235>4'));

Вернет '14'

Автор: Dima85 20.3.2008, 16:13
Как все сложно. А неужели проще решениев нет?

Автор: Rrader 20.3.2008, 16:15
Цитата

Как все сложно. А неужели проще решениев нет?

Парсинг строки. Все очень просто smile 

Автор: Alix 20.3.2008, 16:29
имхо, это не оптимально, удалять по одному символу, особенно для больших строк. Я бы сделал так:
Код
Function PreprocessStr(const AOrig: String): String;
var
  i       : integer;
  lastPos : integer;
  len     : integer;

Begin
  i   := 1;
  len := length(AOrig);
  lastPos := 1;

  while i <= len do begin
    if AOrig[i] = '<' then begin
        Result := Result + copy(AOrig, lastPos, i - lastPos);

        while (i <= len) and (AOrig[i] <> '>') do inc(i);
        lastPos := i+1;
    end;

    inc(i);
  end;

  // copy the rest
  if lastPos <= len then
    Result := Result + copy(AOrig, lastPos, len - lastPos + 1);
end;

Автор: MetalFan 20.3.2008, 16:29
можно с пом.регулярки в 1 строку

Добавлено через 3 минуты и 43 секунды
качаешь http://RegExpStudio.com
подключаешь uses RegExpr
и пишешь 
Код

lResultStr := ReplaceRegExpr( '<.*?>', lSourceStr, '' );

Автор: Poseidon 20.3.2008, 16:34
Цитата(Dima85 @  20.3.2008,  15:57 Найти цитируемый пост)
Есть:s: string;В ней хранится текст до 5500 символов.


Мне вот интересно стало, как можно в string запихнуть строку длинее 255 символов???

Автор: Alix 20.3.2008, 16:35
Цитата(Poseidon @  20.3.2008,  16:34 Найти цитируемый пост)
Мне вот интересно стало, как можно в string запихнуть строку длинее 255 символов???

если это AnsiString, а в дельфе так по-умолчанию и есть, то почему бы нет?

Добавлено через 1 минуту и 54 секунды
Цитата
можно с пом.регулярки в 1 строку

не стоит их юзать там, где можно без них легко обойтись

Автор: Poseidon 20.3.2008, 17:00
Воть, мой вариант smile

Код
Function PreprocessStr(AOrig: String): String;
var
SPos, FPos: integer;
tmp: string;
begin
while True do
  begin
  SPos:= Pos('<',AOrig);
  FPos:= Pos('>',AOrig);
  tmp:= copy(AOrig, SPos, FPos-SPos+1);
  if (SPos=0)or(FPos=0) then break;
  AOrig:= StringReplace(AOrig, tmp, '', []);
  end;
  Result:= AOrig;
end;

Автор: Dima85 20.3.2008, 17:02
Я знаю вот таким способом можно удалять символы с строчки

Код

Delete(s, Pos('-', s), Length(S));


Так может есть какое-то аналогичное решение, что-то наподобие:
Код

Delete(s, Pos('<.*?>', s), Length(S));


м?

Автор: Poseidon 20.3.2008, 17:07
Хех, точно! Что-то я подзабыл про Delete. 

Код
Function PreprocessStr(AOrig: String): String;
var
SPos, FPos: integer;
begin
while True do
  begin
  SPos:= Pos('<',AOrig);
  FPos:= Pos('>',AOrig);
  if (SPos=0)or(FPos=0) then break;
  Delete(AOrig, SPos, FPos-SPos+1);
  end;
  Result:= AOrig;
end;

 smile 

Автор: MetalFan 20.3.2008, 17:12
Цитата(Alix @  20.3.2008,  16:35 Найти цитируемый пост)
не стоит их юзать там, где можно без них легко обойтись 

обоснуй. разве что если критично быстродействие

Автор: ama_kid 20.3.2008, 17:17
Цитата(Dima85 @  20.3.2008,  15:57 Найти цитируемый пост)
Необходимо все символы которые находится в <тут> удалить, вместе с <>. 
Я бы сделал как-то так:
Код
procedure TForm1.Button1Click(Sender: TObject);
var
 SourceStr,TmpStr:string;
 EndPos:integer;
begin
 SourceStr:='1231<4234>6<4345>785<adffg>68';
 repeat
  TmpStr:=SourceStr;
  Delete(SourceStr,Pos('<',SourceStr),Pos('>',SourceStr)-Pos('<',SourceStr)+1);
 until (TmpStr=SourceStr);
 ShowMessage(SourceStr);
end;

Автор: Poseidon 20.3.2008, 17:24
Цитата(ama_kid @  20.3.2008,  17:17 Найти цитируемый пост)
Я бы сделал как-то так:
Ну, во-первых не вижу особой разницы с моим кодом. Разве что вместо результата функций подставил сами функции (так, кстати, никто не делает т.к. читать код сложно становится). А еще не понятно зачем  EndPos объявлять smile

А вообще "вопрос решен" нужно делать уже. Примеров достаточно

Автор: Alix 20.3.2008, 17:28
Цитата(MetalFan @  20.3.2008,  17:12 Найти цитируемый пост)
обоснуй. разве что если критично быстродействие 

Да, именно из этих соображений. Всему есть предел и иногда удобство программирования не оправдывает потерь скорости.

Имхо, мое решение для больших строк лучше. Попробую объяснить. Например, у Rrader - слишком много удалений по одному символу. У 
Poseidon, это исправлено, но мне кажется неверным способ, когда происходят постоянные удаления из середины строки. В его способе, как и в моем, происходит постоянная работа с памятью, но у меня она только растет (за счет append'a к result), а у него еще и копирование неслабого кол-ва символов. (Да, 5кб копирнуть - это фигня по нынешним временам, но мало ли что...) Если бы не было ключевых слов о том, что строки будут длинными, я бы и не заморачивался.

Автор: Poseidon 20.3.2008, 17:36
У меня http://forum.vingrad.ru/index.php?showtopic=201637&view=findpost&p=1448737 вообще копирования нету. 

Автор: Alix 20.3.2008, 17:38
Цитата(Poseidon @  20.3.2008,  17:36 Найти цитируемый пост)
У меня там вообще копирования нету

ты не понял. Когда происходит удаление символов из строки, то та часть, которая была выше участка удаления потом копируется вниз.

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