Поиск и удаление из TMemo в Delphi - PullRequest
0 голосов
/ 11 марта 2019

У меня есть код для поиска и удаления из заметок. но есть небольшая проблема в том, что, например, строки памятки содержат 1, 11, 12, 13, 21, 22 и т. д., когда e = 1, удаляются все строки, содержащие 1. Мне нужно удалить только определенный поиск (e = 1)

  for i := 0 to memo3.lines.count-1 do
  begin
    if (pos(IntToStr(e), Memo3.Lines[i]) > 0) then begin
      Memo3.Lines.Delete(i);  
      Memo3.Lines.Delimiter := '-';
      Memo3.Lines.StrictDelimiter := True;
      t:= Memo3.Lines.DelimitedText;
      Label5.Caption:=t;
    end;

enter image description here

Ответы [ 2 ]

2 голосов
/ 11 марта 2019

Проверка только для строки

Если вы хотите найти только строку в отдельности, вам придется посмотреть, нет ли цифр до и после строки:

NumStr := IntToStr(e);
Str := Memo3.Lines[i];
NumPos := Pos(NumStr, Str);
if NumPos > 0 then
begin
  if (NumPos > 1) and IsDigit(Str[NumPos - 1])) or
     (NumPos < Length(Str)) and IsDigit(Str[NumPos + 1])) then
    Continue; // i.e. skip deleting etc.

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

Одно число в строке?

Теперь, если ваш TMemo содержит ровно одно единственное число в строке , тогда все намного проще, и вам вообще не нужен Pos():

NumStr := IntToStr(e);
for i := Memo3.Lines.Count - 1 downto 0 do
begin
  if NumStr = Memo3.Lines[i] then
  begin
    Memo3.Lines.Delete(i);
    ...
  end;
end;

Обратите внимание, что я не повторял вызов IntToStr() для каждой итерации цикла. Я только что сделал это один раз и присвоил результат вызова NumStr. Вызов функций занимает время.

Удаление в цикле

Если вы хотите удалить из индексированного списка элементов, например, свойство Lines TMemo, то, чтобы не пропустить ни одной строки, всегда выполняйте цикл в обратном порядке, как я это делал выше. Потому что, если вы удалите строку i, все строки после i будут сдвигаться на один индекс вниз, , поэтому при переходе к строке i+1 это будет вторая до следующей строки , а не следующая строка (, потому что она получила индекс i после удаления ).

Но при обратном цикле предыдущая строка будет i-1, и этот индекс не изменился.

Простой пример:

Исходная ситуация:

index: text
0:     A
1:     B
2:     C  <-- delete!
3:     D
4:     E

После удаления:

0:     A
1:     B
2:     D <-- now at index 2, was at index 3
3:     E <-- now at index 3, was at index 4

Если вы удалите C по индексу 2, тогда D и E пойдут вниз на один индекс, и теперь D по индексу 2. Но восходящий цикл увеличивается i до 3, так что теперь вы проверяете строку 3, и D никогда не проверяется . Но если вы пойдете вниз, тогда i станет 1, и это не изменило индекс и все еще содержит B .

1 голос
/ 11 марта 2019

При изменении строк в заметке путем удаления вы не можете перейти от 0 к счетчику - 1, потому что индекс меняется каждый раз, когда вы удаляете строку

Этот цикл удалит все строки, содержащие значение в e

for i := Memo3.Lines.Count - 1 downto 0 do
begin
  if pos(e, Memo3.Lines[i]) > 0 then
  begin
    Memo3.Lines.Delete(i);
  end;
end;

Однако я понятия не имею, что должны делать другие строки кода в вашем образце, может быть, вы можете уточнить, что вы пытаетесь достичь с помощью этого.

РЕДАКТИРОВАТЬ
Если вы хотите удалить только те строки, которые соответствуют значению в e, используйте этот цикл

Value := IntToStr(e);
for i := Memo1.Lines.Count - 1 downto 0 do
begin
  if Value = Trim(Memo1.Lines[i]) then
  begin
    Memo1.Lines.Delete(i);
  end;
end;
...