【问题标题】:Search and delete from TMemo in delphi在delphi中从TMemo中搜索和删除
【发布时间】:2019-03-11 10:47:15
【问题描述】:

我有一个代码,可以从备忘录行中搜索和删除。但是有一个小问题,例如,备忘录行包含 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;

【问题讨论】:

  • 您需要定义更准确的条件。例如,要删除的字符串是否应该只包含1 而仅此而已?顺便说一句,你的 for 循环不适合删除行,因为计数可能会改变。
  • 我添加了图像文件作为示例。我的代码在 e=1 时删除了 1,11, 31,我只想删除 '1'
  • 所以比较if Memo3.Lines[i] = e,而不是pos
  • 谢谢兄弟。你说的对。没有 pos 效果很好。
  • 查看我的答案,“每行一个数字?” 部分。 你应该从顶部倒数的事实仍然存在。 @MBo 几乎是正确的,如果你将 Integer e 变成一个字符串(我的回答中的 NumStr )。并且不要重复调用 IntToStr(e),只需调用一次并记住结果(在 NumStr 中),在循环之前

标签: delphi delphi-2010


【解决方案1】:

只检查字符串

如果只想孤立地查找字符串,则必须查看字符串前后是否没有数字:

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 周围查找空格、制表符等,并且仅当您发现该数字是该字符串中的单个“单词”时才删除。 p>

每行一个数字?

现在如果你的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。函数调用需要时间。

循环删除

如果您想从项目的索引列表中删除,例如TMemoLines 属性,那么为了不跳过任何行,请始终向后循环,就像我在上面所做的那样。因为如果你删除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

如果您在索引 2 处删除 C,那么 DE 会下降一个索引,现在是 D 位于索引 2。但向上循环将 i 增加到 3,因此现在您检查第 3 行,并且永远不会检查 D。但是如果你往下走,那么i 会变成 1,这并没有改变索引,仍然包含 B

【讨论】:

    【解决方案2】:

    通过删除更改备忘录中的行时,您不能从 0 循环到 count - 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;
    

    【讨论】:

    • 感谢您的帮助。但这段代码没有帮助。 e=2 删除 12、22、2、32、25、23 等
    • 您应该更好地解释e=2时应该删除的内容从您当前的问题中不清楚。它指出在e=1时应删除所有包含1的行,因此在e=2时不适用?
    • @GuidoG:看我的回答。如果 e 是,比如说,'2',他不想删除带有 '92'、'27'、'25' 或 '2456'、'321' 等的字符串,只删除那些包含精确 '2' 的字符串(我不知道字符串中还有什么)。但是 Pos('2', 'ABCD32DEF88') > 0,虽然在那里,数字是 32 和 88,而不是 2。所以仅靠这个测试是不够的。
    • 先生,我想当 e=2 时,它只会删除 2 的备注行文本,而不是 12,22,23,.. 其他词
    • 你的字符串是什么?它们是否每行包含一个数字?在那种情况下,很简单:if Memo3.Lines[i] = Str then Memo3.Lines.Delete ....
    猜你喜欢
    • 2019-08-14
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多