Как сохранить и загрузить список пар ключ-значение в строке?

У меня есть список строк и значений, которые они должны заменить. Я пытаюсь объединить их в список, например 'O'='0',' .'='.', ..., чтобы мне было легко редактировать его и добавлять больше пар замен.

Прямо сейчас лучший способ, которым я мог думать об этом, это:

var
  ListaLimpeza : TStringList;
begin
  ListaLimpeza := TStringList.Create;

  ListaLimpeza.Delimiter := '|';
  ListaLimpeza.QuoteChar := '"';
  ListaLimpeza.DelimitedText := 'O=0 | " .=."';

  ShowMessage('1o Valor = '+ListaLimpeza.Names[1]+' e 2o Valor = '+ListaLimpeza.ValueFromIndex[1]);

Это работает, но это плохо для визуальных эффектов, так как я не могу закодировать строку перед (например, ' .') так (что очень наглядно для символа ПРОБЕЛ), только как (" .), чтобы = работал для назначения имя и значение в TStringList.


person S F    schedule 04.06.2013    source источник
comment
Ваше сообщение было бы НАМНОГО легче читать, если бы вы использовали в своем примере стандартный разделитель и символы кавычек. Работает ли ваш пример кода, если вы его используете? Я подозреваю, что вы неправильно используете эти символы в задании DelimitedText. Но я бросил попытки распутать ваш пример, когда столкнулся со странным выбором персонажей. Предложение: вы получите лучшие ответы на SA, если будете придерживаться стандартных значений по умолчанию, а не | и !, если вы не можете решить проблему со стандартами. Возможно, здесь у кого-то еще хватит мозгов и смелости копаться в ваших.   -  person RobertFrank    schedule 04.06.2013
comment
Я сделал некоторые правки, я думаю, что теперь это более понятно. Не могли бы вы проверить, пожалуйста.   -  person S F    schedule 04.06.2013
comment
Рассматривали ли вы вопрос об отделении того, как вы редактируете список, от того, как вы его храните? Для редактирования попробуйте использовать сетку из двух столбцов, чтобы вам не приходилось беспокоиться о заключении в кавычки или разделении. Затем сохраните строки, как хотите. Не беспокойтесь о том, чтобы сохранить их в удобном для чтения формате; просто убедитесь, что он может быть однозначно загружен вашей программой.   -  person Rob Kennedy    schedule 04.06.2013
comment
Если ваш код не делает то, что вы ожидаете, вам нужно его отладить. Используйте отладчик, поставляемый с Delphi.   -  person Rob Kennedy    schedule 04.06.2013
comment
Я считаю, что проблема в StringReplace. Вы знаете об этом, не уважая пробелы?   -  person S F    schedule 04.06.2013
comment
Это было бы намного проще, если бы вы использовали что-то вроде JSON. Вы пытаетесь заново изобрести колесо.   -  person David Heffernan    schedule 04.06.2013
comment
Я отменил ваше последнее редактирование, потому что оно изменило весь смысл и цель вопроса. После того, как на вопрос получен ответ, вы не можете изменить весь вопрос, потому что это делает недействительными ответы, которые вы уже получили. Если у вас теперь есть вопрос о замене строк, его следует опубликовать как новый отдельный вопрос. Вы можете вернуться к этому оттуда для контекста и истории.   -  person Ken White    schedule 04.06.2013


Ответы (1)


Names и Values по умолчанию должны быть разделены = в стиле INI-файлов Windows. Невозможно изменить этот разделитель AFAICT. Как указывает @SirRufo в комментарии (и чего я никогда не замечал), вы можете изменить это, используя свойство TStringList.NameValueSeparator.

Это даст вам представление о том, что Delphi думает о вашем TStringList, а не о том, что вы думаете:

procedure TForm1.FormCreate(Sender: TObject);
var
  SL: TStringList;
  Temp: string;
  i: Integer;
begin
  SL := TStringList.Create;
  SL.Delimiter := '|';
  SL.QuoteChar := '"';
  SL.StrictDelimiter := True;
  SL.DelimitedText := 'O=0 | ! .!=!.!';
  Temp := 'Count: ' + IntToStr(SL.Count) + #13;
  for i := 0 to SL.Count - 1 do
    Temp := Temp + Format('Name: %s Value: %s'#13, 
              [SL.Names[i], SL.ValueFromIndex[i]]);
  ShowMessage(Temp);
end;

Это производит этот вывод:

Пример вывода ShowMessage из приведенного выше кода

TStringList Names/Values, вероятно, не будет делать то, что вам нужно. Неясно, какова ваша реальная цель, но похоже, что простой текстовый файл с простым списком text|replacement и простым разбором этого файла будет работать, и вы можете легко использовать TStringList для чтения/записи из этого файла, но я не Я не вижу никакого способа легко выполнить синтаксический анализ, кроме как сделать это самостоятельно. Вы можете использовать массив для хранения пар при их разборе:

type
  TReplacePair = record
    TextValue: string;
    ReplaceValue: string;
  end;

  TReplacePairs = array of TReplacePair;

function GetReplacementPairs: TReplacePairs;
var
  ConfigInfo: TStringList;
  i, Split: Integer;
begin
  ConfigInfo := TStringList.Create;
  try
    ConfigInfo.LoadFromFile('ReplacementPairs.txt');
    SetLength(Result, ConfigInfo.Count);
    for i := 0 to ConfigInfo.Count - 1 do
    begin
      Split := Pos('|`, ConfigInfo[i];
      Result[i].TextValue := Copy(ConfigInfo[i], 1, Split - 1);
      Result[i].ReplaceValue := Copy(ConfigInfo[i], Split + 1, MaxInt);
    end;
  finally
    ConfigInfo.Free;
  end;
end;

Затем вы можете заполнить любые элементы управления, необходимые для редактирования/добавления/удаления пар замены, и просто отменить операцию чтения, чтобы записать их обратно для сохранения.

person Ken White    schedule 04.06.2013
comment
Да, я понимаю. Я считаю, что мне нужно будет перейти к другому подходу, я думаю об использовании: '|O|==|0| , | .|==|.| , ...' в строке, а затем с помощью кода, чтобы разобрать его, чтобы определить правильные замены. Есть ли более простое решение, которое дало бы мне такой визуальный код? - person S F; 04.06.2013
comment
Я предложил решение, но встроенная функция TStringList не поможет. Однако вы всегда можете создать своего собственного потомка, который сделает это за вас. - person Ken White; 04.06.2013
comment
Символ NameValueSeparator можно изменить с помощью свойства TStrings.NameValueSeparator docwiki. embarcadero.com/Libraries/XE2/ru/ - person Sir Rufo; 04.06.2013
comment
@SirRufo: Спасибо, чувак, я не знал об этой собственности, и это сделает мою жизнь намного проще :) - person Marjan Venema; 04.06.2013
comment
@SirRufo: я тоже никогда не замечал этого свойства (очевидно, оно мне не нужно). Спасибо. Я обновил свой ответ (конечно, с должным указанием). - person Ken White; 04.06.2013