Любой способ получить TStringList.CommaText, чтобы не экранировать запятые с кавычками? - PullRequest
2 голосов
/ 10 июня 2010

Я делаю некоторую работу с генерацией кода, и одна из вещей, которые мне нужно сделать, это создать вызов функции, где одним из параметров является вызов функции, например:

result := Func1(x, y, Func2(a, b, c));

TStringList.CommaText очень полезен для генерации списков параметров, но когда я пересекаю дерево для построения вызова внешней функции, то, что я в итоге получаю, выглядит так:

result := Func1(x, y, "Func2(a, b, c)");

Он цитирует третий аргумент, потому что он содержит запятые, и это приводит к неверному коду. Но я не могу сделать что-то упрощенное, например StringReplace, все двойные кавычки с пустыми строками, потому что вполне возможно, что аргументом функции может быть строка с двойными кавычками внутри. Есть ли способ сделать так, чтобы он не выходил за пределы строк, содержащих запятые?

Ответы [ 7 ]

4 голосов
/ 10 июня 2010

Вы можете установить QuoteChar в качестве пробела, и вы просто получите несколько лишних пробелов в выводе, что в целом нормально, так как сгенерированный код обычно не выглядит симпатично. Строковые литералы будут затронуты, хотя; они будут вставлены дополнительные пробелы, изменяя значение строки.

Класс TStrings Free Pascal использует StrictDelimiter, чтобы контролировать, происходит ли цитирование при чтении свойства DelimitedText. Когда это true , цитирование вообще не происходит. Возможно, Delphi относится к этому свойству одинаково.

1 голос
/ 11 июня 2010

А как насчет использования Unicode-версии AnsiExtractQuotedStr для удаления кавычек?

1 голос
/ 10 июня 2010

Мы написали класс-потомок TStringList, в котором переопределено свойство DelimitedText.Вы можете скопировать большую часть кода из оригинальной реализации.

1 голос
/ 10 июня 2010

Напишите свой собственный метод для экспорта содержимого вашего TStringList в строку.

function MyStringListToString(const AStrings: TStrings): string;
var
    i: Integer;
begin
    Result := '';
    if AStrings.Count = 0 then
        Exit;
    Result := AStrings[0];
    for i := 1 to AStrings.Count - 1 do
        Result := Result + ',' + AStrings[i];
end;

Слишком очевидно? : -)

В качестве альтернативы, что произойдет, если вы установите StringList.QuoteChar на #0 и затем вызовете StringList.DelimitedText?

1 голос
/ 10 июня 2010
  1. Создание массива «маловероятных символов»: без ключа, например , или даже без печати, например # 129, # 141, #143, # 144 .
  2. Убедитесь, что у вас нет 1-го маловероятного в вашем StringList.CommaText.Или переходите к следующему маловероятно, пока не получите тот, который не используется в вашем StringList.CommaText.(Утверждаю, что вы найдете его)
  3. Используйте этот маловероятный символ в качестве QuoteChar для вашего StringList
  4. Get StringList.DelimitedText.Вы получите QuoteChar вокруг параметров функции, таких как: result := Func1(x, y, †Func2(a, b, c)†);
  5. Замените маловероятное QuoteChar (здесь ) пустыми строками ...
0 голосов
/ 23 марта 2016

Была такая же проблема, вот как я это исправил:

s := Trim(StringList.Text)

вот и все; -)

0 голосов
/ 11 июня 2010
var
  LList: TStringList;
  s, LOutput: string;
begin
  LList := TStringList.Create;
  try
    LList.Add('x');
    LList.Add('y');
    LList.Add('Func2(a, b, c)');
    for s in LList do
      LOutput := LOutput + s + ', ';
    SetLength(LOutput, Length(LOutput) - 2);
    m1.AddLine('result := Func1(' + LOutput + ')');
  finally
    LList.Free;
  end;
end;
...