Pregunta

Estoy escribiendo una utilidad (que está en Python) que está generando salida en forma de un script TCL. Dada una variable de cadena arbitraria (no unicode) en la pitón, quiero producir una línea TCL como

set s something

... que establecerá la variable TCL 's'A esa cadena exacta, independientemente de qué caracteres extraños hay en ella. Sin ser demasiado extraño, no quiero hacer que la salida sea más desordenada de lo necesario. Creo que un enfoque decente es

  1. Si la cadena no está vacía y contiene solo alfanuméricos, y algunos personajes como .-_ (pero definitivamente no $"{}\) entonces se puede usar como es;

  2. Si contiene solo caracteres imprimibles y sin cotas dobles o aparatos ortopédicos rizados (y no termina en barra inalcanzada), simplemente coloque {} alrededor;

  3. De lo contrario, poner "" alrededor de él después de usar \ escapa para " { } \ $ [ ] , y \nnn escapa para personajes no imprimidos.

Pregunta: ¿Es ese el conjunto completo de caracteres que necesitan escapar de las citas dobles? No puedo encontrar esto en los documentos. Y me perdí algo (casi me perdí esas cuerdas porque (2) no puedo terminar en por ejemplo).

Sé que hay muchas otras cuerdas que pueden citarse {}, pero parece difícil identificarlos fácilmente. Además, parece que los caracteres no imprimentes (en particular, Newline) están bien con (2) si no le importa que estén literalmente presentes en la salida de TCL.

¿Fue útil?

Solución

Realmente solo necesitas 2 reglas,

  • Escapar de los frenos rizados
  • Envuelva la salida en aparatos ortopédicos rizados

No necesita preocuparse por las nuevas líneas, caracteres no imprimibles, etc. Son válidos en una cadena literal, y TCL tiene un excelente soporte de 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}
}

EditarA la luz de su comentario, puede hacer lo siguiente:

  • Escapar [] {} y $
  • envolver toda la salida en set s [subst { $output } ]

La belleza de TCL es que tiene una gramática muy simple. No hay otros personajes además de los 3 anteriores necesarios para ser escapados.

Edición 2 Un ultimo intento.

Si pasas subst Algunas opciones, solo necesitarás escapar \ y {}

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

Sin embargo, necesitaría encontrar una regex para convertir caracteres no imprimibles en sus códigos escapados.

¡Buena suerte!

Otros consejos

TCL tiene muy pocos metacharacteres una vez que estás dentro de una cadena de doble cotización, y todos ellos se pueden citar colocando una barra de barras frente a ellos. Los personajes que debes citar son \ sí mismo, $ y [, pero se considera una buena práctica para citar también ], { y } para que el script en sí sea incrustable. (TCL propio list El comando hace esto, excepto que en realidad no envuelve las cotizaciones dobles, por lo que también maneja las barras barras y también intentará usar otras técnicas en cadenas "agradables". Hay un algoritmo para hacer esto, pero aconsejo no molestarme con tanta complejidad en su código; Las reglas universales simples son mucho mejores para la codificación correcta).

El segundo paso es llevar los datos a TCL. Si está generando un archivo, su mejor opción es escribirlo como UTF-8 y usar el -encoding opción para tclsh/wish o para el source Comando para indicar explícitamente cuál es la codificación. (Si está dentro del mismo proceso, escriba los datos de UTF-8 en una cadena y evalúe eso. Job hecho). Esa opción (introducida en TCL 8.5) es específicamente para tratar este tipo de problema:

source -encoding "utf-8" theScriptYouWrote.tcl

Si eso no es posible, tendrá que recurrir a agregar citas adicionales. Lo mejor es asumir que solo tiene el soporte ASCII disponible (un buen denominador común más bajo) y cita todo lo demás Como un paso separado para la cita descrita en el primer párrafo. Para citar, convierta cada carácter unicode de U+00080 hasta una secuencia de escape de la forma \uXXXX donde xxxx son exactamente cuatro dígitos hexagonales[1] y los otros dos son personajes literal. No uses el \xXX Forma, ya que tiene algunas malas más malas "sorprendentes" (por desgracia).


[1] Hay un error abierto en TCL sobre el manejo de caracteres fuera del panel multilingüe básico, parte de los cuales es que el \u La forma no puede hacer frente. Afortunadamente, los personajes que no son de PMP siguen siendo razonablemente raros en la práctica.

Para hacerlo bien, también debe especificar la codificación de su cadena Python, generalmente sys.getDefaultEncoding (). De lo contrario, puede garflear codificaciones al traducirlo a TCL.

Si tiene datos binarios en su cadena y desea cadenas binarias TCL como resultado, esto siempre funcionará:

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

Sin embargo, se verá como un vertedero hexadecimal, pero bueno, es un basurero hexagonal ...

Si usa cualquier codificación especial como UTF-8, puede mejorarlo un poco utilizando la codificación ConvertFrom/ConvvertTo y el idioma de Python apropiado.

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

Por supuesto, puede refinar esto un poco, evitando la codificación de todos los caracteres no especiales, pero lo anterior es seguro en cualquier caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top