2016-05-13 91 views
-1

文本我有一个具有以下数据的文本文件:解析德尔福

dgm P1 
s0:->b1 
*s1:b2->b1 
S2:b2->b1,b3 
dgm P2 
s0:->b2 
*s1:b1,b3->b2 

我要分析此文件,以获得一个数组,其元素将包含每个 DGM年代,直到下一个。也就是说,第一个元素是:

dgm P1 
s0:->b1 
*s1:b2->b1 
S2:b2->b1,b3 

第二个元素是:

dgm P2 
s0:->b2 
*s1:b1,b3->b2 

等 请我如何去在德尔福。我正在寻找更好的方法来做到这一点。我试着从文件加载到TStringList。

begin 
str:=TstringList.Create; 
try 
str.LoadFromFile('example.txt'); 
for i:=0 to str.Count -1 do 
if str[i] ='dgm' then 
//get the position, add it to an array; 
//get the next position, till the end; 
//use the positions to divide up the string 

finally 
str.Free; 

但是,这是行不通的,我也觉得可能是一个更好的办法 来处理这个比我简要介绍。

+0

什么不工作呢?你需要花时间来阅读[help]和[mcve]。 –

+1

':='是赋值,使用'='进行比较。您可能会更好地读出前3个字符与'dgm'比较的rs。如何区分大小写?空白?这种语言的规则是什么?你知道吗?你知道如何执行字符串的基本操作吗?看起来你没有。如果你不知道,那么你会奋斗。 –

+1

它不工作,因为你检查'dmg'字符串,但文件有'dmg P1','dmg P2'等 而你需要替换:= with =,正如David指出 –

回答

2

AS。这个答案使用了Delphi 2010+的特性,因为它是在topicstarter指定了他的目标Delphi版本之前编写的。尽管如此,这些代码仍然可以作为他自己实现的框架,使用他可用的库和语言功能。

function ParseDgmStringsList(const str: TStrings): TArray<TArray<String>>; 
var 
    s: string; 
    section: TList<String>; 
    receiver: TList<TArray<String>>; 

    procedure FlushSection; 
    begin 
    if section.Count > 0 then begin 
     receiver.Add(section.ToArray()); 
     section.Clear; 
    end; 
    end; 
begin 
    section := nil; 
    receiver := TList<TArray<String>>.Create; 
    try 
    section := TList<String>.Create; 

    for s in str do begin 
     if StartsText('dgm ', s) then // or StartsStr 
     FlushSection; 
     section.Add(s); 
    end; 

    FlushSection; 
    Result := receiver.ToArray(); 
    finally 
    receiver.Destroy; 
    section.Free; 
    end; 
end; 

http://docwiki.embarcadero.com/Libraries/Seattle/en/System.Generics.Collections.TList_Properties

PS。请注意,“使用AnsiContainsStr(str,'dgm')”很脆弱并且几乎不正确 - 它会在S2:b2->bcdgmaz,b3这样的行上产生误报。 您应该检查dgm启动字符串,它是一个独立的单词,而不是一些随机的长单词的一部分(即搜索'dgm' + #32,而不是单纯的'dgm'

PPS。另一个要考虑的是,你将如何处理与非DGM线开始的文件吗?你会用空行,缩进的行?例如你将如何分析这样的文件怎么办?

s8:->b2 
;*s1:b1,b3->b2 
dgm P1 
s0:->b1 
*s1:b2->b1 

S2:b2->b1,b3 
    dgm P2 
    s0:->b2 
*s1:b1,b3->b2 
+0

感谢一堆!文件中的数据实际上与我所提供的完全一致,否则会引发错误,表示输入错误。你的回答超出了这个范围,但我很高兴接受它。 – Mekicha

+0

@Emeka如果'else else抛出错误表示错误的输入',那么我认为你应该扩展我在上面起草的解析器,以便它明确地适应或失败的任何可能的不规则。例如,使用案例忽略StartsText适用于案例不规范。您可以添加'Trim'或'TrimLeft'调用等。另外我假设'dgm'后面跟着空格字符,但是如果紧随tab(#9)或其他分隔符等,它也可能是有效的。检测分隔线许多复杂,所以你会更好地卸载到另一个功能,但复杂 –

+0

哦耶谢谢。会考虑这一点。 – Mekicha