Domanda

Sto scrivendo un programma di utilità (che risulta essere in pitone) che sta generando output nella forma di uno script TCL. Data una variabile stringa arbitraria (non Unicode) in pitone, voglio produrre una linea di TCL come

set s something

... che imposterà TCL variabile 's' per la stringa esatta, indipendentemente da ciò che strani personaggi sono in esso. Senza entrare troppo strano, non voglio fare il Messier uscita del necessario. Credo che un approccio decente è

  1. se la stringa non è vuota e contiene solo caratteri alfanumerici e alcuni caratteri come .-_ (ma sicuramente non $"{}\) allora può essere usato così com'è;

  2. se contiene solo caratteri stampabili e senza virgolette o parentesi graffe (e non finisce in backslash) poi semplicemente mettere {} attorno ad esso;

  3. In caso contrario, mettere "" attorno ad esso dopo aver usato \ sfugge per " { } \ $ [ ] e fughe \nnn per i caratteri non stampabili.

Domanda: è che la serie completa di caratteri che devono fuggire dentro le virgolette? Non riesco a trovare questo nella documentazione. E mi è sfuggito qualcosa (ho quasi perso che le stringhe per (2) non possono terminare in \ per esempio).

So che ci sono molte altre stringhe che possono essere offerti dai {}, ma sembra difficile identificarli facilmente. Inoltre, sembra che i caratteri non stampabili (in particolare, nuova riga) sono OK con (2), se non ti dispiace loro di essere letteralmente presente in uscita TCL.

È stato utile?

Soluzione

È davvero solo bisogno di 2 regole,

  • Escape parentesi graffe
  • Avvolgere l'uscita tra parentesi graffe

Non è necessario preoccuparsi di ritorni a capo, caratteri non stampabili ecc Essi sono validi in una stringa letterale, e TCL ha un ottimo supporto Unicode.

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}
}

Modifica Alla luce del vostro commento, è possibile effettuare le seguenti operazioni:

  • fuga [] {} e $
  • avvolgere l'intero output in set s [subst { $output } ]

La bellezza di Tcl è un ha una grammatica molto semplice. Non ci sono altri personaggi oltre il 3 di cui sopra doveva essere sfuggito.

Modifica 2 Un ultimo tentativo.

Se si passa subst alcune opzioni, si avrà solo bisogno di fuggire \ e {}

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

Si avrebbe bisogno di venire con una regex per convertire i caratteri non stampabili ai loro codici fuggiti tuttavia.

In bocca al lupo!

Altri suggerimenti

Tcl ha pochissime metacaratteri una volta che sei all'interno di una stringa con virgolette doppie, e tutti loro può essere citato mettendo un backslash davanti a loro. I caratteri si deve citare sono \ sé, $ e [, ma è buona norma citare anche ], { e } in modo che lo script stesso è integrabile. (Proprio comando list di Tcl fa questo, se non che in realtà non avvolgere le virgolette in modo che si occupa anche di backslash e sarà anche cercare di utilizzare altre tecniche sulle stringhe “bello”. C'è un algoritmo per fare questo, ma io non consigliare assaggiarlo più di tanto la complessità nel codice;. semplici regole universali sono molto meglio per una corretta codifica)

Il secondo passo è quello di ottenere i dati in Tcl. Se si crea un file, la soluzione migliore è quella di scrivere come UTF-8 e utilizzare l'opzione -encoding a tclsh / desiderio o al comando source dichiarare esplicitamente ciò che la codifica è. (Se sei dentro lo stesso processo, i dati in una stringa e scrittura 8 UTF-valutare che lavoro fatto..) Tale facoltà (introdotta in Tcl 8.5) è specificamente per affrontare questo tipo di problema:

source -encoding "utf-8" theScriptYouWrote.tcl

Se questo non è possibile, si sta andando ad avere per ripiegare ad aggiungere ulteriore citando. La cosa migliore è quella di allora supporre che hai solo supporto ASCII disponibile (un buon minimo comune denominatore) e citare tutto il resto come un passaggio separato per il quoting di cui al primo comma . Per citare, convertire ogni carattere Unicode da U + 00080 fino a una sequenza di escape della forma \uXXXX dove XXXX sono esattamente quattro cifre hex [1] e gli altri due sono caratteri letterali. Non utilizzare il modulo \xXX, come che ha alcune caratteristiche ineleganti “sorprendente” (ahimè).


[1] C'è un bug aperto in Tcl sulla gestione personaggi al di fuori del riquadro multilingue di base, parte dei quali è che la forma \u non è in grado di far fronte. Fortunatamente, i caratteri non BMP sono ancora abbastanza rari in pratica.

Per farlo bene si dovrebbe anche specificare la codifica la stringa in pitone è, tipicamente sys.getdefaultencoding (). In caso contrario, si potrebbe ingarbugliare codifiche quando si traduce a Tcl.

Se si dispone di dati binari nella stringa e si vuole Tcl stringhe binarie di conseguenza questo funziona sempre:

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

sarà simile a un dump esadecimale, però, ma bene, è una discarica hex ...

Se si utilizza qualsiasi codifica speciale come UTF-8 è possibile migliorare un po 'che utilizzando la codifica ConvertFrom / convertto e il linguaggio Python appropriata.

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

Ovviamente si può definire questa un po ', evitando il \ u codifica di tutti i caratteri non speciali, ma quanto sopra è sicuro in ogni caso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top