简体   繁体   English

Delphi Tstringlist,将字符串作为带引号的逗号分隔字符串获取?

[英]Delphi Tstringlist, get strings as a quoted, comma delimited string?

I have a Tstringlist containing a list of keys used in a database table.我有一个包含数据库表中使用的键列表的 Tstringlist。 I'd like a simple way to generate one string containing all the keys, with each separated by a comma and enclosed in single quotes.我想要一种简单的方法来生成一个包含所有键的字符串,每个字符串用逗号分隔并用单引号括起来。 This is so that it can be used in a SQL 'IN' statement eg WHERE FieldX IN ('One','Two','Three') .这样它就可以在 SQL 'IN' 语句中使用,例如WHERE FieldX IN ('One','Two','Three')

I've tried using quotechar but it is ignored when reading the commatext.我试过使用quotechar,但在阅读逗号文本时它被忽略了。 eg the following code例如下面的代码

procedure junk;
var
  SL : Tstringlist;
  s : string;
begin
 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.QuoteChar := ''''; //single quote around strings
 SL.Add('One');
 SL.Add('Two');
 SL.Add('Three');
 try
   s :=  SL.commatext;
   showmessage(s);
 finally
   SL.Free;
 end; //finally
end; //junk

shows the message One,Two,Three - without any quotes.显示消息一、二、三 - 不带任何引号。

I know I can do it the long way round, as in我知道我可以做很长的路,就像

procedure junk;
var
  SL : Tstringlist;
  s : string;
  i : integer;
begin
 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.Add('One');
 SL.Add('Two');
 SL.Add('Three');
 try
 s := '';
 for I := 0 to SL.Count - 1 do
    begin
    s := s +  ',' + '''' + SL[i] + '''';
    end;
 delete(s,1,1);
 showmessage(s);
 finally
   SL.Free;
 end;//finally
end;

but is there a simpler way using properties of the Tstringlist itself?但是有没有更简单的方法使用 Tstringlist 本身的属性?

Use sl.DelimitedText instead of sl.CommaText to make it follow your settings.使用sl.DelimitedText而不是sl.CommaText使其遵循您的设置。 CommaText will temporarily change the Delimiter and QuoteChar to some hardcoded values. CommaText将临时将DelimiterQuoteChar更改为一些硬编码值。

If you're using D2006 or later, you can use a CLASS HELPER:如果您使用的是 D2006 或更高版本,则可以使用 CLASS HELPER:

USES Classes,StrUtils;

TYPE
  TStringListHelper = CLASS HELPER FOR TStrings
                        FUNCTION ToSQL : STRING;
                      END;

FUNCTION TStringListHelper.ToSQL : STRING;
  VAR
    S : STRING;

  FUNCTION QuotedStr(CONST S : STRING) : STRING;
    BEGIN
      Result:=''''+ReplaceStr(S,'''','''''')+''''
    END;

  BEGIN
    Result:='';
    FOR S IN Self DO BEGIN
      IF Result='' THEN Result:='(' ELSE Result:=Result+',';
      Result:=Result+QuotedStr(S)
    END;
    IF Result<>'' THEN Result:=Result+')'
  END;

This code:这段代码:

SL:=TStringList.Create;
SL.Add('One');
SL.Add('Two');
SL.Add('Number Three');
SL.Add('It''s number 4');
WRITELN('SELECT * FROM TABLE WHERE FIELD IN '+SL.ToSQL);

will then output:然后将输出:

SELECT * FROM TABLE WHERE FIELD IN ('One','Two','Number Three','It''s number 4')

CommaText (and apparently also DelimitedText) can not be relied on to add the quotes, because they treat single word and multi word strings differently.不能依赖 CommaText(显然还有 DelimitedText)来添加引号,因为它们对单个单词和多单词字符串的处理方式不同。

When retrieving CommaText, any string in the list that include spaces, commas or quotes will be contained in double quotes, and any double quotes in a string will be repeated.检索 CommaText 时,列表中包含空格、逗号或引号的任何字符串都将包含在双引号中,并且字符串中的任何双引号都会重复。

There doesn't seem to be any combination with the TStringList alone, so I suggest you add the strings using QuotedStr .似乎没有单独与 TStringList 的任何组合,因此我建议您使用QuotedStr添加字符串。 Following settings work as you wish, regardless of, whether strings are single words or multi words:无论字符串是单字还是多字,以下设置都可以按您的意愿工作:

 SL := Tstringlist.Create;
 SL.Delimiter :=','; //comma delimiter
 SL.StrictDelimiter := True;
// SL.QuoteChar := ''''; //single quote around strings
// SL.Add('One');
// SL.Add('Two words');
// SL.Add('Three');
 SL.Add(QuotedStr('One'));
 SL.Add(QuotedStr('Two words'));
 SL.Add(QuotedStr('Three'));
 s := SL.CommaText; // or SL.DelimitedText;
 showmessage(s);

Output is:输出是:

'One','Two words','Three' “一”、“二字”、“三”

The TStrings.DelimitedText methods quote only the strings when needed: when there's something link O'ne this will print as 'O''ne' - ie it double the quotes. TStrings.DelimitedText方法仅在需要时引用字符串:当有链接O'ne它将打印为'O''ne' - 即它使引号加倍。

You can achieve what you want setting a convenience delimiter and the QuoteChar property to the #0 value and then replacing the delimiters with the quotes.您可以实现您想要的设置方便分隔符和QuoteChar属性为#0值,然后用引号替换分隔符。

procedure junk;
var
  sl : Tstringlist;
  s: string;
begin
  sl := Tstringlist.Create;
  try
    sl.Delimiter := '|';
    sl.QuoteChar := #0;//no quote
    sl.Add('On''e');
    sl.Add('Two');
    sl.Add('Three');

    //escape the single quotes
    s := StringReplace(sl.DelimitedText, '''', '''''', [rfReplaceAll]);

    //replace the delimiters and quote the text
    s := '''' +  StringReplace(s, sl.Delimiter, ''',''', [rfReplaceAll]) + '''';

    WriteLn(s);

  finally
    sl.Free;
  end;
end;

我已经解决了类似的问题:

  s := ''' + StringReplace(sl.CommaText, ',', ''',''', [rfReplaceAll]) + '''

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM