2010-06-10 5 views
2

Je fais un travail avec la génération de code, et l'une des choses que je dois faire est de créer un appel de fonction où l'un des paramètres est un appel de fonction, comme ceci:N'importe quel moyen d'obtenir TStringList.CommaText pour ne pas échapper les virgules avec des guillemets?

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

TStringList.CommaText est très utile pour générer des listes de paramètres, mais quand je traverse l'arbre pour construire l'appel de fonction externe, ce que je finis avec ressemble à ceci:

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

il est cité le troisième argument, car il contient des virgules, et produit code invalide. Mais je ne peux pas faire quelque chose de simpliste comme StringReplace toutes les guillemets doubles avec des chaînes vides, car il est tout à fait possible qu'un argument de fonction puisse être une chaîne avec des guillemets à l'intérieur. Y a-t-il un moyen de ne pas échapper aux lignes contenant des virgules?

+0

Vous pouvez analyser avec une expression régulière? – Remko

+6

... et alors j'aurais deux problèmes. : P –

+2

@Remko, il génère du * code *, sans l'analyser. S'il est courant que vous analysiez immédiatement le code que vous venez de générer, vous vous trompez. –

Répondre

1
  1. construire un tableau de caractères "improbables": non-keyable comme , ou même non imprimables comme # 129, # 141, # 143, # 144.
  2. Vérifiez que vous n'avez pas le 1er peu probable n'importe où dans votre StringList.CommaText. Ou passer à la prochaine improbable jusqu'à ce que vous en obteniez un non utilisé dans votre StringList.CommaText. (Affirmez que vous trouvez une)
  3. Utilisez cette improbable char comme le QuoteChar pour votre StringList
  4. Get StringList.DelimitedText. Vous aurez la QuoteChar autour des paramètres de la fonction comme: result := Func1(x, y, †Func2(a, b, c)†);
  5. Remplacer le QuoteChar improbable (ici ) par des chaînes vides ...
+1

Je ne peux m'empêcher de penser à "une série de personnages improbables" qui me rappelle "Une série d'événements malheureux". :-) –

1

Écrivez votre propre méthode pour exporter le contenu de votre TStringList à un 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; 

Trop évident? :-)

Alternativement, que se passerait-il si vous définissez StringList.QuoteChar à #0 et ensuite appelé StringList.DelimitedText?

+0

On dirait qu'une AV se passe avec 'QuoteChar = # 0'. C'était surprenant. –

+1

Ou définir QuoteChar pour l'espace –

4

Vous pouvez définir QuoteChar comme étant un espace, et vous obtiendriez simplement des espaces supplémentaires dans la sortie, ce qui est généralement OK car le code généré ne devrait normalement pas être joli. Les littéraux de chaîne seraient affectés, cependant; ils auraient des espaces supplémentaires insérés, en changeant la valeur de la chaîne.

Free Pascal's TStrings class utilise StrictDelimiter pour contrôler si une citation se produit lors de la lecture de la propriété DelimitedText. Quand c'est vrai, la citation ne se produit pas du tout. Peut-être que Delphi traite cette propriété de la même manière.

+1

La VCL de Delphi 2010 appelle 'AnsiQuotedStr' avant d'ajouter un élément à la chaîne de sortie. 'StrictDelimiter' n'a aucune incidence sur les guillemets dans Delphi. – afrazier

+0

Delphi a une propriété StrictDelimiter, mais cela fonctionne un peu différemment. –

1

Nous avons écrit une classe descendante de TStringList dans laquelle réimplémenté la propriété DelimitedText. Vous pouvez copier la majeure partie du code de l'implémentation d'origine.

0
 
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; 
1

Qu'en est-il en utilisant la version Unicode de AnsiExtractQuotedStr pour supprimer les citations?

+0

+1 pour le facteur kludge pur: D Heath Robinson style ftw! –

0

eu le même problème, voici comment je l'ai fixé:

s := Trim(StringList.Text) 

qui est tout ;-)

Questions connexes