You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Delphi DFM属性清理工具误删相似名称属性

解决Delphi DFM属性清理工具误删相似名称属性的问题

你的问题根源很明确:原来的StrIPos(mPropList.Lines[K] + ' =', S)是子串匹配,当要删除的属性名是Prop时,SecondProp = ...这行里的Prop =会被当作子串命中,导致误删包含目标属性名的其他属性。

要实现精确匹配,我们需要提取DFM行中完整的属性名再做匹配,因为DFM的属性行格式通常是[前导空格]属性名 = 值/结构,核心思路是:

  • 先去除行的前导空格,找到第一个=的位置,提取等号前的部分作为当前行的属性名
  • 将提取出的属性名与目标属性名做不区分大小写的精确匹配

下面是修改后的完整Button2Click代码,我标注了关键修改的部分:

procedure TfrmDeleteProp_MainForm.Button2Click(Sender: TObject);
var
  LFile, LSource, LResult: TStringList;
  I, J, K, Processed, WasError, Removed: Integer;
  SkipPropData: Boolean;
  FLOpt: TFileListOptions;
  S, CurrentProp: String;
  EqualsPos: Integer; // 新增:存储等号的位置
begin
  LFile := TStringList.Create;
  LSource := TStringList.Create;
  LResult := TStringList.Create;
  try
    if chbxSubFolders.Checked then
      FLOpt := [flFullNames, flRecursive]
    else
      FLOpt := [flFullNames];
    if not AdvBuildFileList(IncludeTrailingBackslash(edPath.Text) + '*.DFM', faAnyFile, LFile, FLOpt) then
    begin
      MessageBox(Handle, 'Invalid path specified. Can not process.', 'Warning', MB_OK or MB_ICONEXCLAMATION);
      exit;
    end;
    Processed := 0;
    WasError := 0;
    for I := 0 to LFile.Count - 1 do
    begin
      LSource.LoadFromFile(LFile[I]);
      Removed := 0;
      for K := 0 to mPropList.Lines.Count - 1 do
      begin
        if K > 0 then
          LSource.Assign(LResult);
        if Trim(mPropList.Lines[K]) = '' then
          continue;
        LResult.Clear;
        SkipPropData := False;
        for J := 0 to LSource.Count - 1 do
        begin
          S := Trim(LSource[J]);
          if SkipPropData then
          begin
            if (S > '') and (S[Length(S)] in [')', '}']) then
              SkipPropData := False;
            continue;
          end;

          // --- 开始修改部分 ---
          CurrentProp := '';
          EqualsPos := Pos('=', S);
          if EqualsPos > 0 then
          begin
            // 提取等号前的部分,去除末尾空格,得到当前属性名
            CurrentProp := Trim(Copy(S, 1, EqualsPos - 1));
          end;
          // 做不区分大小写的精确匹配
          if StrIComp(PChar(CurrentProp), PChar(mPropList.Lines[K])) <> 0 then
          // --- 结束修改部分 ---
          begin
            LResult.Add(LSource[J]);
            continue;
          end;

          if (S > '') and (S[Length(S)] in ['(', '{']) then
            SkipPropData := True;
          Removed := Removed + 1;
        end;
      end;
      if Removed > 0 then
      begin
        if RenameFile(LFile[I], ChangeFileExt(LFile[I], '.BAK')) then
        begin
          LResult.SaveToFile(LFile[I]);
          Processed := Processed + 1;
        end
        else
        begin
          MessageBox(Handle, PChar('Can not create back up copy for file: ' + LFile[I] + #13#10'File is not processed.'), 'Warning', MB_OK or MB_ICONEXCLAMATION);
          WasError := WasError + 1;
        end;
      end;
    end;
    MessageBox(Handle, PChar(Format('Total files found: %d'#13#10'Properties were removed from: %d'#13#10'Error files: %d', [LFile.Count, Processed, WasError])), 'Statistics', MB_OK or MB_ICONINFORMATION);
  finally
    LFile.Free;
    LSource.Free;
    LResult.Free;
  end;
end;

修改说明:

  1. 新增了EqualsPos变量用来定位行中第一个=的位置,CurrentProp存储提取出的当前行属性名
  2. 替换了原来的子串匹配逻辑,改为提取完整属性名后做精确的不区分大小写匹配,这样就不会误删SecondProp这类包含目标属性名的其他属性
  3. 保留了原有的SkipPropData逻辑,确保正确处理多行结构的属性(比如Font = { ... }这种需要跳过后续行的情况)

这个修改后,工具只会删除完全匹配目标属性名的行,不会再误删相似名称的属性了。

内容的提问来源于stack exchange,提问作者User421

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 07:42:27