Общее цитирование строки для TCL
Вопрос
Я пишу утилиту (которая оказалась в Python), которая генерирует выход в виде сценария TCL. Учитывая некоторую произвольную строковую переменную (не Unicode) в Python, я хочу создать линию TCL, подобную
set s something
... что установит переменную TCL 's
«Точной строке, независимо от того, какие странные символы в ней. Не становясь слишком странным, я не хочу делать выходной поверхности, чем это необходимо. Я считаю, что приличный подход
Если строка не пустая и содержит только буквенный
.-_
(но определенно нет$"{}\
) тогда его можно использовать как есть;Если он содержит только печатные символы и без двойных цитатов или вьющихся скобок (и не заканчивается в обратной складе), просто просто положите
{}
вокруг него;В противном случае положи
""
вокруг него после использования\
убегает за"
{
}
\
$
[
]
, а также\nnn
сбегает за не печатными персонажами.
Вопрос: Это полный набор символов, которые нуждаются в сбеге внутри двойных цитат? Я не могу найти это в документах. И я что -то пропустил (я почти пропустил эти строки для (2), например, не могу закончить , например).
Я знаю, что есть много других строк, которые можно процитировать {}
, но кажется трудно их легко идентифицировать. Кроме того, похоже, что не печатные персонажи (в частности, Newline) в порядке с (2), если вы не возражаете против их буквально присутствовать на выводе TCL.
Решение
Вам действительно нужно только 2 правила,
- Побежать вьющиеся брекеты
- Обернуть выход в вьющиеся скобки
Вам не нужно беспокоиться о новичках, не печатных символах и т. Д. Они действительны в буквальной строке, а TCL обладает отличной поддержкой 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}
}
РедактироватьВ свете вашего комментария вы можете сделать следующее:
- побег
[]
{}
а также$
- обернуть весь вывод в
set s [subst { $output } ]
Красота TCL - это очень простая грамматика. Нет других персонажей, кроме 3 выше, необходимого избежать.
Редактировать 2 Последняя попытка.
Если вы пройдете subst
Некоторые варианты вам нужно будет только сбежать \
а также {}
set s [subst -nocommands -novariables { $output } ]
Вам нужно было бы придумать корпорацию, чтобы преобразовать не печатные символы в их сбежавшие коды, однако.
Удачи!
Другие советы
У TCL очень мало метахарактеров, как только вы находитесь в строке с двойным цитированием, и все они могут быть процитированы, положив перед ними обратную черту. Персонажи, которых вы должны цитировать \
сам, $
а также [
, но считается хорошей практикой также цитировать ]
, {
а также }
так что сам сценарий встроен. (Собственный TCL list
Команда делает это, за исключением того, что на самом деле он не обертывает двойные кавычки, поэтому она также обрабатывает обратную черту, а также будет пытаться использовать другие методы на «красивых» струнах. Есть алгоритм для этого, но я советую не беспокоиться о такой сложности в вашем коде; Простые универсальные правила намного лучше для правильного кодирования.)
Второй шаг - получить данные в TCL. Если вы генерируете файл, ваш лучший вариант-написать его в качестве UTF-8 и использовать -encoding
вариант TCLSH/желание или source
командование явно указать, что такое кодирование. (Если вы находитесь в том же процессе, запишите данные UTF-8 в строку и оцените это.
source -encoding "utf-8" theScriptYouWrote.tcl
Если это невозможно, вам придется вернуться к добавлению дополнительных цитат. Лучше всего предположить, что у вас есть только поддержка ASCII (хороший самый низкий общий знаменатель) и процитировать все остальное В качестве отдельного шага к цитированию, описанному в первом абзаце. Анкет Чтобы процитировать, преобразовать каждый символ Unicode из U+00080 до последовательности выхода формы \uXXXX
где xxxx ровно четыре цифры[1] А два других - буквальные персонажи. Не используйте \xXX
Форма, так как это имеет некоторые «удивительные» неспособности (увы).
[1] В TCL есть открытая ошибка об обработке персонажей вне основной многоязычной панели, часть из которых \u
Форма не в состоянии справиться. К счастью, не BMP-персонажи все еще достаточно редки на практике.
Чтобы сделать это правильно, вы также должны указать кодирование вашей строки Python, как правило, sys.getDefaultencoding (). В противном случае вы можете исказить кодировки при переводе на TCL.
Если у вас есть двоичные данные в вашей строке, и в результате это всегда будет работать бинарные строки TCL, это всегда будет работать:
data = "".join("\\u00%02x" % ord(c) for c in mystring)
tcltxt = "set x %s" % data
Похоже на шестнадцатеричную свалку, но это шестнадцатеричная свалка ...
Если вы используете какое-либо специальное кодирование, например, UTF-8, вы можете немного улучшить это, используя кодирование ConvertFom/Convertto и соответствующую идиому Python.
data = "".join("\\u00%02x" % ord(c) for c in myutf8string)
tcltext = "set x [encoding convertfrom utf-8 %s]" % data
Вы, конечно, можете немного уточнить это, избегая кодирования всех не специальных ChARS, но вышеупомянутое в любом случае безопасно.