2016-05-13 120 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