【问题标题】:Any way to get TStringList.CommaText to not escape commas with quotes?有什么方法可以让 TStringList.CommaText 不使用引号转义逗号?
【发布时间】:2010-06-10 17:57:15
【问题描述】:

我正在做一些代码生成工作,我需要做的一件事是创建一个函数调用,其中一个参数是函数调用,如下所示:

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

TStringList.CommaText 对于生成参数列表非常有用,但是当我遍历树构建外部函数调用时,我最终得到的结果如下所示:

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

它引用了第三个参数,因为它包含逗号,并且产生了无效代码。但是我不能做一些简单的事情,比如 StringReplace all double quotes with empty strings,因为函数参数很可能是一个带有双引号的字符串。有什么办法让它不逃避包含逗号的行吗?

【问题讨论】:

  • 你可以用正则表达式解析它吗?
  • ...然后我会遇到两个问题。 :P
  • @Remko,他在生成代码,而不是解析它。如果您通常的做法是立即解析刚刚生成的代码,那您就错了。
  • 我相信内置代码的 TStringList 是“接近,但没有雪茄”。说“自己写”的答案非常简单。 :-)
  • @Rob:没错。我将解析这段代码,但要等到以后。

标签: delphi code-generation escaping tstringlist


【解决方案1】:

您可以将QuoteChar 设置为一个空格,并且您只会在输出中获得一些额外的空格,这通常是可以的,因为通常不期望生成的代码看起来很漂亮。不过,字符串文字会受到影响;他们会插入额外的空格,从而改变字符串的值。

Free Pascal's TStrings class 使用StrictDelimiter 来控制读取DelimitedText 属性时是否发生引用。当它为 true 时,根本不会出现引用。也许 Delphi 以同样的方式处理该属性。

【讨论】:

  • Delphi 2010 的 VCL 在向输出字符串添加元素之前调用 AnsiQuotedStrStrictDelimiter 在 Delphi 中完全不影响引用。
  • Delphi 有一个 StrictDelimiter 属性,但它的工作方式有点不同。
【解决方案2】:
  1. 构建“不太可能的字符”数组:不可键入,如 ,甚至不可打印,如 #129、#141、#143 , #144
  2. 确认您的StringList.CommaText 中没有第一个不太可能的地方。或者移到下一个不太可能的位置,直到您的StringList.CommaText 中没有使用。 (断言你找到了)
  3. 将此不太可能的字符用作您的 StringList 的 QuoteChar
  4. 获取StringList.DelimitedText。您将在函数参数周围获得QuoteChar,例如:result := Func1(x, y, †Func2(a, b, c)†);
  5. 用空字符串替换不太可能的QuoteChar(此处为)...

【讨论】:

  • “一系列不太可能的角色”让我想起了“一系列不幸事件”。 :-)
【解决方案3】:

使用 Unicode 版本的 AnsiExtractQuotedStr 删除引号怎么样?

【讨论】:

    【解决方案4】:

    编写您自己的方法将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,会发生什么情况?

    【讨论】:

    • 看起来像 QuoteChar = #0 发生了 AV。这令人惊讶。
    【解决方案5】:

    我们编写了一个 TStringList 的后代类,其中重新实现了 DelimitedText 属性。您可以从原始实现中复制大部分代码。

    【讨论】:

      【解决方案6】:
      变量 LList:TStringList; s,L输出:字符串; 开始 LList := TStringList.Create; 尝试 LList.Add('x'); LList.Add('y'); LList.Add('Func2(a, b, c)'); 对于 LList 中的 s 做 LOutput := LOutput + s + ', '; SetLength(LOutput, 长度(LOutput) - 2); m1.AddLine('结果 := Func1(' + LOutput + ')'); 最后 LList.免费; 结尾; 结尾;

      【讨论】:

        【解决方案7】:

        遇到了同样的问题,我是这样解决的:

        s := Trim(StringList.Text)
        

        就是这样;-)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-18
          • 2020-02-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-23
          • 1970-01-01
          相关资源
          最近更新 更多