2016-05-13 3 views
-1

У меня есть текстовый файл, который имеет следующие данные:Разбор текста в Delphi

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 

и т.д. Пожалуйста, как я идти о том, что в Delphi. Я ищу лучший способ сделать это. Я попробовал загрузку из файла в 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 символа rs сравнения с 'dgm'. Как насчет чувствительности к регистру? Пробелы? Каковы правила этого языка? Вы знаете? Вы знаете, как выполнять основные операции над строками? Похоже, вы этого не делаете. Если вы не знаете, тогда вы будете бороться. –

+1

Он не работает, потому что вы проверяете строку «dmg», но файл имеет «dmg P1», «dmg P2» и т. Д. И вам нужно заменить: = с =, поскольку Дэвид указывает –

ответ

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'

ПФС. Другое дело, рассмотреть вопрос о том, как бы вы справиться файлы, начинающиеся с-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 ошибка выбрасывается, означающая« плохой вход », тогда я думаю, что вы должны расширить обработчик, который я написал выше, чтобы он явно вмещал или терпел неудачу при любой возможной неравномерности. Например, с использованием игнорирования случая StartsText допускает ошибки в работе. Вы можете добавить вызовы 'Trim' или' TrimLeft' и т. Д. Также я предполагаю, что за 'dgm' следует пробел char, но, возможно, он также будет действителен, если будет следовать вкладка (# 9) или какой-либо другой разделитель и т. Д. Обнаружение разделитель линии muight получить реальный комплекс, так что вы бы лучше разгрузить его до еще одной функции, как бы сложной –

+0

о, спасибо. Подумайте об этом. – Mekicha