Frage

Ich schreibe ein Dienstprogramm (das zufällig in Python ist), das Ausgabe in Form eines TCL -Skripts erzeugt. Bei einer beliebigen String -Variablen (nicht unicode) im Python möchte ich eine TCL -Linie erstellen wie

set s something

... die TCL -Variable festlegen 's'Zu dieser genauen Zeichenfolge, unabhängig davon, welche seltsamen Charaktere darin sind. Ohne zu seltsam zu werden, möchte ich die Ausgabe nicht chaotischer machen als nötig. Ich glaube, ein anständiger Ansatz ist

  1. Wenn die Zeichenfolge nicht leer ist und nur alphanumerische und einige Charaktere wie enthält .-_ (aber definitiv nicht $"{}\) dann kann es als Is verwendet werden;

  2. Wenn es nur druckbare Zeichen und keine Doppelquote oder lockigen Zahnspangen enthält (und nicht in Backslash endet), dann setzen Sie einfach ein {} um es herum;

  3. Ansonsten ausgedrückt "" um es herum nach der Verwendung \ entkommt für " { } \ $ [ ] , und \nnn entkommt für nicht druckende Charaktere.

FRAGE: Ist das der vollständige Zeichen von Zeichen, die in Doppelzitaten entkommen müssen? Ich kann das in den Dokumenten nicht finden. Und habe ich etwas vermisst (ich habe diese Saiten fast verpasst, weil (2) beispielsweise nicht enden kann).

Ich weiß, dass es viele andere Zeichenfolgen gibt, die von zitiert werden können {}, aber es scheint schwierig, sie leicht zu identifizieren. Außerdem sieht es so aus, als ob nicht druckende Charaktere (insbesondere Newline) mit (2) in Ordnung sind, wenn es Ihnen nichts ausmacht, dass sie buchstäblich in der TCL-Ausgabe präsent sind.

War es hilfreich?

Lösung

Sie brauchen wirklich nur 2 Regeln,

  • Entkommen lockige Zahnspangen
  • Wickeln Sie den Ausgang in lockige Klammern ein

Sie müssen sich keine Sorgen um Neulinien, nicht druckbare Zeichen usw. machen. Sie sind in einer wörtlichen Zeichenfolge gültig, und TCL verfügt über eine hervorragende Unicode -Unterstützung.

set s { 
this is
a 
long 
string. I have $10 [10,000 cents] only curly braces \{ need \} to be escaped.
\t is not  a real tab, but '    ' is. "quoting somthing" :
{matchin` curly braces are okay, list = string in tcl}
}

BearbeitenIn Anbetracht Ihres Kommentars können Sie Folgendes tun:

  • Flucht [] {} und $
  • Wickeln Sie den gesamten Ausgang ein set s [subst { $output } ]

Die Schönheit von TCL ist, dass es eine sehr einfache Grammatik hat. Es gibt keine anderen Charaktere außer den 3 oben, die entkommen werden mussten.

Bearbeiten 2 Ein letzter Versuch.

Wenn Sie bestehen subst Einige Optionen müssen Sie nur entkommen \ und {}

set s [subst -nocommands -novariables { $output } ]

Sie müssten jedoch eine Regex entwickeln, um nicht druckbare Zeichen in ihre entkommenen Codes umzuwandeln.

Viel Glück!

Andere Tipps

TCL hat nur sehr wenige Metacharacer, sobald Sie sich in einer doppelt zitierten Saite befinden, und alle können zitiert werden, indem ein Backglash vor sie gestellt wird. Die Zeichen, die Sie zitieren müssen, sind \ selbst, $ und [, aber es gilt als eine gute Praxis, auch zu zitieren ], { und } so dass das Skript selbst eingebettet ist. (TCL ist eigen list Der Befehl erledigt dies, außer dass es die Doppelzitate nicht wirklich einpackt, sodass er auch Backslashs behandelt und auch versucht wird, andere Techniken für „schöne“ Zeichenfolgen anzuwenden. Es gibt einen Algorithmus dafür, aber ich empfehle, mich nicht um so viel Komplexität in Ihrem Code zu kümmern. Einfache universelle Regeln sind viel besser für die korrekte Codierung.)

Der zweite Schritt besteht darin, die Daten in TCL zu bringen. Wenn Sie eine Datei generieren, ist Ihre beste Option, sie als UTF-8 zu schreiben und die zu verwenden -encoding Option zu Tclsh/Wunsch oder an die source Befehl, explizit anzugeben, was die Codierung ist. (Wenn Sie sich im selben Prozess befinden, schreiben Sie UTF-8-Daten in eine Zeichenfolge und bewerten Sie dies. Job erledigt.) Diese Option (eingeführt in TCL 8.5) dient speziell für den Umgang mit solchen Problemen:

source -encoding "utf-8" theScriptYouWrote.tcl

Wenn das nicht möglich ist, müssen Sie wieder auf zusätzliche Zitate hinzufügen. Das Beste ist, dann davon auszugehen, dass Sie nur ASCII -Unterstützung zur Verfügung gestellt haben (ein gut niedrigster gemeinsamer Nenner) und alles andere zitieren als separater Schritt zum im ersten Absatz beschriebenen Zitat. Um zu zitieren, konvertieren Sie jedes Unicode -Zeichen von U+00080 bis zu einer Fluchtsequenz der Form \uXXXX wobei xxxx genau vier Sechskantstellen sind[1] und die anderen beiden sind wörtliche Charaktere. Verwenden Sie nicht das \xXX Form, da dies einige „überraschende“ Fehlfehler (Achs) hat.


[1] Es gibt einen offenen Fehler in TCL über die Behandlung von Charakteren außerhalb des grundlegenden mehrsprachigen Bereichs. Teil davon ist das, dass das \u Form ist nicht in der Lage, damit fertig zu werden. Glücklicherweise sind in der Praxis nicht immer noch einigermaßen selten.

Um es richtig zu machen, sollten Sie auch angeben, dass die Codierung Ihrer Python -Zeichenfolge in der Regel sys.getDefaultCoding () ist. Andernfalls können Sie Codierungen übertragen, wenn Sie es in TCL übersetzen.

Wenn Sie binäre Daten in Ihrer Zeichenfolge haben und dadurch TCL -Binärzeichenfolgen wünschen, funktioniert dies immer:

data = "".join("\\u00%02x" % ord(c) for c in mystring)
tcltxt = "set x %s" % data

Ich werde allerdings wie eine Hex -Müllkippe aussehen, aber es ist eine Hex -Müllkippe ...

Wenn Sie eine spezielle Codierung wie UTF-8 verwenden, können Sie diesen Bit verbessern, indem Sie Coding Convertfrom/converto und die entsprechende Python-Idiom verwenden.

data = "".join("\\u00%02x" % ord(c) for c in myutf8string)
tcltext = "set x [encoding convertfrom utf-8 %s]" % data

Sie können dies natürlich ein wenig verfeinern und die u -Codierung aller nicht speziellen Zeichen vermeiden, aber die oben genannte ist auf jeden Fall sicher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top