Any way to get TStringList.CommaText to not escape commas with quotes?
I'm doing some work with code generation, and one of the things I need to do is create a function call where one of the parameters is a function call, like so:
result := Func1(x, y, Func2(a, b, c));
TStringList.CommaText is very useful for generating the parameter lists, but when I traverse the tree to build the outer function call, what I end up with looks like this:
result := Func1(x, y, "Func2(a, b, c)");
It's quoting the third argument because it contains commas, and that pr开发者_StackOverflow社区oduced invalid code. But I can't do something simplistic like StringReplace all double quotes with empty strings, because it's quite possible that a function argument could be a string with double quotes inside. Is there any way to make it just not escape the lines that contain commas?
You could set QuoteChar
to be a space, and you'd merely get some extra spaces in the output, which is generally OK since generated code isn't usually expected to look pretty. String literals would be affected, though; they would have extra spaces inserted, changing the value of the string.
Free Pascal's TStrings
class uses StrictDelimiter
to control whether quoting occurs when reading the DelimitedText
property. When it's true, quoting does not occur at all. Perhaps Delphi treats that property the same way.
- Build an array of "unlikely characters" : non-keyable like †, ‡ or even non-printable like #129, #141, #143, #144.
- Verify you don't have the 1st unlikely anywhere in your
StringList.CommaText
. Or move to the next unlikely until you get one not used in yourStringList.CommaText
. (Assert that you find one) - Use this unlikely char as the
QuoteChar
for your StringList - Get
StringList.DelimitedText
. You'll get theQuoteChar
around the function parameters like:result := Func1(x, y, †Func2(a, b, c)†);
- Replace the unlikely
QuoteChar
(here †) by empty strings...
What about using the Unicode version of AnsiExtractQuotedStr to remove the quotes?
Write your own method to export the contents of your TStringList
to a string.
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;
Too obvious? :-)
Alternatively, what would happen if you set StringList.QuoteChar
to #0
and then called StringList.DelimitedText
?
We have written a descendant class of TStringList in which reimplemented the DelimitedText property. You can copy most of the code from the original implementation.
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;
Had the same problem, here's how I fixed it:
s := Trim(StringList.Text)
that's all ;-)
精彩评论