Delphi 德尔菲:如何动态地;“拆分”;根据(动态)掩码将字符串转换为子字符串

Delphi 德尔菲:如何动态地;“拆分”;根据(动态)掩码将字符串转换为子字符串,delphi,string,pascal,Delphi,String,Pascal,这就是我的情况:我有一个文本文件,其中包含许多表示要加载到SQL DB表中的记录的等长字符串,因此我必须从这些字符串生成SQL代码。 我在该数据库上有一个表(我们称之为“格式化表”),它告诉我字符串是如何格式化的,以及在哪里加载它们(该表的每个记录都包含目标表名、字段名、数据位置和从文本文件中引用的字符串的长度) 我已经用每个Delphi程序员都熟悉的方式解决了这个问题,使用Copy(string,pos,length)函数,根据“格式化表”中的信息迭代每个字段。 这很好,但速度很慢,特别是当我

这就是我的情况:我有一个文本文件,其中包含许多表示要加载到SQL DB表中的记录的等长字符串,因此我必须从这些字符串生成SQL代码。
我在该数据库上有一个表(我们称之为“格式化表”),它告诉我字符串是如何格式化的,以及在哪里加载它们(该表的每个记录都包含目标表名、字段名、数据位置和从文本文件中引用的字符串的长度)

我已经用每个Delphi程序员都熟悉的方式解决了这个问题,使用
Copy(string,pos,length)
函数,根据“格式化表”中的信息迭代每个字段。
这很好,但速度很慢,特别是当我们谈到包含一百万行或更多行的源文本文件时,每个行代表几十甚至数百个数据字段

我现在要做的是以一种源字符串已经被拆分的方式“查看”源字符串,避免使用
Copy()
函数不断创建新字符串,从原始字符串复制内容,分配和释放内存等等。我想说的是“我有整个字符串,让我们以一种方式来看待它,在一个步骤中表示它的每个‘片段’(字段),而不从中创建子字符串”

可以解决我的问题的方法是定义一个动态结构,比如动态记录或动态数组(不是Delphy所说的动态数组,更像是“动态静态数组”)来“叠加”字符串,以便从那个角度“观察”它。。。我不知道我对那个解释是否足够清楚。。。然而,据我所知,Delphi并没有实现这种动态结构

这是一段(静态)代码,除了缺乏动态性之外,它实现了我想要的功能

procedure TForm1.FormCreate(Sender: TObject);
type
  PDecodeStr = ^TDecodeStr;
  TDecodeStr = record
    s1: Array[0..3] of AnsiChar;
    s2: Array[0..9] of AnsiChar;
    s3: Array[0..4] of AnsiChar;
    s4: Array[0..7] of AnsiChar;
    s5: Array[0..2] of AnsiChar;
  end;
var
  cWholeStr: AnsiString;
begin
  cWholeStr := '123456789012345678901234567890';
  Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s1);
  Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s2);
  Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s3);
  Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s4);
  Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s5);
end;
你知道怎么解决这个问题吗


提前感谢。

您无法避免创建额外的字符串。问题末尾的示例创建字符串

Memo1.Lines.Add(PDecodeStr(PAnsiString(cWholeStr)).s1)
在此代码中,您对
TStrings.Add()
的调用将根据您传递的参数隐式创建一个动态字符串,然后将该字符串传递给
Add()


使用
Copy
的解决方案可能是一种可行的方法,因为如果您希望对分割字符串执行任何操作,我看不到任何简单的方法来避免复制内存。

我认为在Delphi中,没有比使用Copy更有效的方法了

但另一种解决方案是将所有字符串直接加载到一列临时表中,然后使用SQL查询进行拆分。
总时间取决于许多参数,因此最好的方法是测试

你是说
PDecodeStr(PAnsiString(cWholeStr)).s1实际上从原始字符串创建了一个副本吗?这不是AnsiChar构造的
数组[0..x]强制将该字符串的“视图”设置为某些边界吗?@Bozzy不完全是这样。如果要使用
pdecodest
变量并写入
pdecodest(..)[1]:=“?”
,那么就不会进行复制。但我确信您会希望将您的
pdecodest
传递到函数上,以便执行比较、添加到列表等操作,这将导致复制。Bozzy:使用“调试窗口”->CPU并亲自查看。这可能是从文本导入通用数据的一个很好的解决方案,但在我的具体情况下,我还必须考虑一些问题,这些问题太难或几乎不可能通过纯SQL实现。不过,感谢您提供的替代解决方案。好的,但是您可以保留这些代码注意事项(过滤器?),只允许将“拆分”到数据库服务器。