Delphi - 在某些String之后解析备忘录

时间:2014-08-10 08:24:29

标签: string delphi

我有这样的备忘录:

Mahogany
        Unpolished
        In Stock :  Yes
        Total Stock : 102
Redwood
        Polished
        In Stock :  Yes
        Total Stock : 80
Pine
        Polished
        In Stock :  Yes
        Total Stock : 22

我想只拥有Redwood的Total Stock。

有很多相同的字符串
  

总库存

我不能将此字符串用作我的关键字。所以,我使用“Redwood”,但我不知道如何在“Redwood”之后获得“Total Stock”这一行。

var
  i: Integer;
  s: string;
begin
  for i := 0 to mem0.lines.Count - 1 do
  begin
    if (AnsiContainsStr(mem0.lines[i], 'Redwood')) then
    begin
      // s:= Redwood's total stock, how to do this ?
    end
  end;
end;

3 个答案:

答案 0 :(得分:3)

缺少的代码是:

s := mem0.Lines[i+3];

这假设数据的格式始终与问题中的完全一致。如果该假设有效,则这个简单的代码是最佳解决方案。


使用具有良好解析器和发射器的标准人类可读结构化数据格式(如JSON或YAML)可能更有意义。遗憾的是,对Delphi上的YAML的支持基本上是不存在的,因此留下了JSON。

答案 1 :(得分:3)

你可以试试这个,但就像你原来的代码一样,它有点“脆弱”。因为它假设您正在搜索的文本的布局(特别是您正在搜索的文本打包在TStrings对象中):

function TotalForItem(const ItemName : String; Strings : TStrings) : String;
 var
  i,
  j,
  p : Integer;
  s : string;
  TotalLineIntro : String;
begin
  Result := '';
  TotalLineIntro := 'Total Stock : ';
  for i := 0 to Strings.Count - 1 do
  begin
    if (Pos(ItemName, Strings[i]) > 0) then
    begin
      for j:= i + 1 to Strings.Count - 1 do begin
        p := Pos(TotalLineIntro, Strings[j]);
        if p > 0 then
        begin
          Result := Copy(Strings[j], p + Length(TotalLineIntro), Length(Strings[j]));
          exit;
        end;
      end;
    end
  end;
end;

procedure TForm3.Button1Click(Sender: TObject);
begin
  ShowMessage(TotalForItem('Redwood', Memo1.Lines));
end;

答案 2 :(得分:2)

而不是AnsiContainsStr,您可以使用StartsWith,因为Redwood部分的其余部分都是indentend。

var
  I: Integer;
  TotalStockLine: string;
  MyArray: TArray<string>
begin
  for I := 0 to Memo1.Lines.Count - 1 do
    if Memo.Lines[I].StartsWith('Redwood') then
    begin
      TotalStockLine := Trim(Memo.Lines[I + 3];
      Break;
    end;
  if TotalStockLine <> '' then
  begin
    MyArray := TotalStockLine.Split([':']);
    TotalStock := StrToInt(Trim(MyArray[1]));
  end;

等......这可能会简化一点,但这表明你可以做到这一点。

FWIW,这假设您使用的是XE3或更高版本。否则,您必须使用独立的StartsWith