Delphi 如何快速解析ANSI字符串?

Delphi 如何快速解析ANSI字符串?,delphi,Delphi,我有一个很大的ansi文本文件。该文件包含许多条目(从数百万到数十亿)。每个条目有如下4行: @Instrument:6:73:941:1973#0/1 other stuff2 other stuff3 other stuff4 TYPE RBlock= record // @Instrument:6:73:941:1973#0/1 Instrument: String;

我有一个很大的ansi文本文件。该文件包含许多条目(从数百万到数十亿)。每个条目有如下4行:

@Instrument:6:73:941:1973#0/1
other stuff2
other stuff3
other stuff4
   TYPE
      RBlock= record                                     // @Instrument:6:73:941:1973#0/1
       Instrument: String;                               // Instrument
       Lane: Integer;                                    // 6  
       TileNo: Integer;                                  // 73
       X: integer;                                       // 941
       Y: Integer;                                       // 1973
       Pair: Byte;                                       // could be 1 or 2 
       MultiplexID: AnsiString;                          // #0  <----  I need it as AnsiString
      end;
我对第一行感兴趣。从第一行我需要提取它的内容(数字和字符串)。我正在使用
StringReplace
替换
并用
#13
隔开,然后我将行拆分为如下记录:

@Instrument:6:73:941:1973#0/1
other stuff2
other stuff3
other stuff4
   TYPE
      RBlock= record                                     // @Instrument:6:73:941:1973#0/1
       Instrument: String;                               // Instrument
       Lane: Integer;                                    // 6  
       TileNo: Integer;                                  // 73
       X: integer;                                       // 941
       Y: Integer;                                       // 1973
       Pair: Byte;                                       // could be 1 or 2 
       MultiplexID: AnsiString;                          // #0  <----  I need it as AnsiString
      end;
类型
RBlock=record/@Instrument:6:73:941:1973#0/1
乐器:弦;//仪器
车道:整数;//6.
TileNo:Integer;//73
X:整数;//941
Y:整数;//1973
对:字节;//可能是1或2

MultiplexID:AnsiString;//#0在C/C++中,有一个名为sscanf()的函数用于处理类似的内容

我已经看到了它在Delphi中的一些实现。使用谷歌搜索,因为他们不喜欢你在这里发布指向外部内容的链接,而且发布整个奇怪的库函数的所有源代码,而不仅仅是作为回复的链接,似乎很愚蠢

您还可以尝试使用正则表达式将字符串拆分为多个片段

我不确定这些函数在性能方面与这里提到的字符串函数相比如何,但它们值得考虑


(提示:通过编写专门为这些字符串设计的简短解析器,您将获得最佳性能。)

您需要检查数据并检查可能出现的数据类型。就个人而言,我可能会这样做(第一个例子):

procedure ParseLine(常量aLine:RawByteString;变量aInstrument:string;变量
aLane、aTileNo、aX、aY:整数;var多路ID:Ansistring;var aPair:
字节);
变量
arrayIndex:整数;
索引:整数;
线宽:整数;
NumList:整数的数组[0..3];
I:整数;
多端:整数;
开始
线宽:=长度(直线);
//去拿仪器
索引:=Pos(“:”,aLine);
设置长度(仪器,索引-2);
对于I:=2到索引-1 do
a仪器[I-1]:=Char(aLine[I]);
//求整数
数组索引:=0;
FillMemory(@NumList,SizeOf(NumList),0);
而(索引

这可以进一步优化,但这将真正影响可读性。这里的问题将是数据对于这个例程是否有效。它将处理一个太短的字符串,但不是文本中的无效值,尽管太短时不会返回错误。负数也会是一个问题。您需要查看的是您的数据,它是什么样子的,发生损坏或无效数据的可能性有多大,以及速度对您有多重要。这是一种平衡行为。您可以删除所有检查并加快速度,或者添加更多检查以降低速度。

我确信,使用上一个问题中的代码,您可以使用一个函数来生成其中一个记录,而这两个字符串只需要一对堆分配。谈谈瓶颈!StringReplace很可能是其中之一。如果你做了一些工作,也许值得在@RudyVelthuis上使用它,你是对的。我使用not ReplaceChar代替了ReplaceString,它确实快得多。谢谢。来自备用格式的值将在哪些变量中结束?另一个问题,是否可能有负值或只有正值?-1用于建议使用正则表达式来解析来自已知和不变源格式的数据。投诉是“字符串解析代码性能差”,而你的建议是正则表达式?(你的“提示”也毫无意义,因为这是问题的全部主题:“我需要一个用于这些字符串的自定义解析器”。“好的。提示:你可以通过为这些字符串编写一个简短的解析器来获得最佳性能。”“任何关于如何更快地阅读它的想法都将受到欢迎。”一些正则表达式库(例如TRegExp)预编译模式并生成一个内部映射,该映射通常比暴力盲字符串搜索和替换算法运行得更快。我曾经编写代码,在包含数十兆字节基因组数据的庞大文件中搜索常见的子表达式。当你处理这样的大数据集时,你不能依赖直觉关于。您的结果不仅对算法非常敏感,而且对您正在搜索的数据模式也非常敏感。事实上,一个已编译的正则表达式可以非常有效。为什么它包含净反对票?我认为这是一个关于一个经常没有得到足够尊重讨论的主题的极好问题。很明显,这里的一些答案是不是基于处理大量字符串数据的经验,这些数据需要进行少量的非平凡分析。任何花时间开发遗传和基因组数据导入例程的人都知道,预先判断任何给定字符串处理方法的解析性能都是愚蠢的,因为大多数时间如果没有大量的预分析,ance是不可预测的!这是一种方法。可能是,也可能是