【发布时间】:2016-01-13 15:01:07
【问题描述】:
我从客户那里读取文件,我需要处理读取的数据并删除一些不需要的字符。我的函数有效,但我正在尝试改进 FixData 函数以提高速度/性能和可维护性。
是否可以将多个 StringReplace 调用替换为仅循环一次数据并替换为所需的任何内容?
我找不到 MultipleStringReplace 或类似函数。
MCVE:
function FixData(const vStr:string):string;
var i:integer;
begin
Result:=vStr;
// empty string
if Result = #0 then Result := '';
// fix just New line indicator
if Result = #13#10 then Result := #8;
// remove 'end'/#0 characters
if Pos(#0, Result) > 0 then
for i := 1 to Length(Result) do
if Result[i] = #0 then
Result[i] := ' ';
// #$D#$A -> #8
if Pos(#$D#$A, Result) > 0 then
Result := StringReplace(Result, #$D#$A, #8, [rfReplaceAll]);
// remove 
if Pos('
', Result) > 0 then
Result := StringReplace(Result, '
', '', [rfReplaceAll]);
// #$A -> #8
if Pos(#$A, Result) > 0 then
Result := StringReplace(Result, #$A, #8, [rfReplaceAll]);
// replace " with temp_replacement value
if Pos(chr(34), Result) > 0 then
Result := StringReplace(Result, chr(34), '\_/', [rfReplaceAll]);
end;
procedure TForm1.Button1Click(Sender: TObject);
var vStr,vFixedStr:string;
begin
vStr:='testingmystr:"quotest" - '+#0+' substr 
 new line '#$A' 2nd line '#$D#$A' end of data';
vFixedStr:=FixData(vStr);
end;
【问题讨论】:
-
是否可以将多个 StringReplace 调用替换为仅循环一次数据并替换为所需的任何内容? 是的。是什么阻止你这样做?分配一个输出字符串。循环输入字符串,将字符复制到输出字符串中。如果检测到需要替换的字符,请替换它。
-
也许使用正则表达式是更好的选择?
-
@daryal,他提到了“速度/性能和可维护性”...
-
@MikeTorrettinni ReplaceStr 最糟糕的部分是,当新旧 [atterns 的大小不同时,要完成昂贵的内存复制。实际上这并不是什么新鲜事,这是任何类似数组的容器的教科书属性:随机访问和替换非常便宜,但插入/删除元素非常昂贵。所以这通常是第一个性能优化——在保持代码可读性的同时尽可能少地复制内存。实际上,在我的 sn-p 中,我可以避免复制字符串块,而是生成块的“坐标”,以便稍后一次性复制。
-
这将提供预先分配确切数量的内存并减少
InputString数据的一份内存副本。但这会使代码更难掌握。大多数基于性能的优化都将不同的逻辑阶段融合到相同的执行单元中,从而模糊了逻辑结构并使维护变得更加困难。相反,我可以分离没有重叠的阶段,并且代码在概念上更容易理解,但在执行中的优化程度较低。您说的是“速度/性能和可维护性”,但通常这是一种权衡,非此即彼,
标签: string delphi delphi-xe7