如何转义通过用户输入收到的乳胶代码?

Posted

技术标签:

【中文标题】如何转义通过用户输入收到的乳胶代码?【英文标题】:How can I escape latex code received through user input? 【发布时间】:2011-11-07 22:27:11 【问题描述】:

我从用户输入的 GUI 文本框中读入一个字符串,并通过pandoc 处理它。该字符串包含带有反斜杠字符的数学乳胶指令。我想将字符串作为原始字符串发送到 pandoc 进行处理。但是像“\theta”这样的东西变成了标签和“heta”。

如何将包含反斜杠字符的字符串文字转换为原始字符串...?

编辑:

感谢 develerx、飞羊和 unutbu。但是没有一个解决方案似乎对我有帮助。原因是还有其他反斜杠字符在 python 中没有任何影响,但在乳胶中确实有意义。

例如'\lambda'。建议的所有方法都会产生

\\lambda

在乳胶处理中没有经过——它应该保持为 \lambda。

另一个编辑:

如果我能完成这项工作,我想我应该完成。 @Mark:这三种方法都给出了我不想要的答案。

a='\nu + \lambda + \theta'; 
b=a.replace(r"\\",r"\\\\"); 
c='%r' %a; 
d=a.encode('string_escape');
print a

u + \lambda +   heta
print b

u + \lambda +   heta
print c
'\nu + \\lambda + \theta'
print d
\nu + \\lambda + \theta

【问题讨论】:

您确定该字符串确实包含\\lambda 并且在您打印时不只是加倍吗?尝试打印mystring[1:],看看里面是否还有\ 。应该有一些一致性 - 如果\t 正在转换为制表符,那么\\ 应该转换为\ 您能否发布从 GUI 文本框中接收到的字符串的 repr,并显示您用于通过 pandoc 处理它的代码? 您的测试不切实际。您不是从文本框中获取它,而是使用字符串文字对其进行设置,并且在将其分配给a 时,Python 已经以不一致的方式对其进行了转换。那时不可能恢复您的原始文本。 我很抱歉。我在从 GUI 读取文本时犯了一个愚蠢的错误。现在问题已经解决了。感谢您的cmets,很抱歉给您带来困扰。 请注意,这个问题并不完全是关于原始字符串的;这是关于转义乳胶代码。 OP错误地认为它们是同一件事。对于实际上关于将特殊字符转换为转义序列的问题,请参阅here。 【参考方案1】:

如果您想将现有字符串转换为原始字符串,那么我们可以像下面这样重新分配它

s1 = "welcome\tto\tPython"
raw_s1 = "%r"%s1
print(raw_s1)

将打印

welcome\tto\tPython

【讨论】:

我相信,至少在 Python3 中,这实际上会打印出:'welcome\\tto\\tPython' -- 包括单引号。 @disflux 我刚刚用 Python 3.3.6 测试了它并打印出来:>>> s1 = "welcome\tto\tPython" >>> raw_s1 = "%r"%s1 >>> print(raw_s1) 'welcome\tto\tPython' python 新手。谁能解释一下这里使用的简单技巧是什么? >>> s1 = "welcome\tto\tPython" >>> raw_s1 = "%r"%s1 >>> s2 = r"welcome\tto\tPython" >>> raw_s1 == s2 错误 这只是repr 的伪装。而且它并没有真正正确地回答问题。【参考方案2】:

我花了很多时间在互联网上尝试不同的答案,我怀疑某件事对某些人有效而对其他人无效的原因是由于应用程序中非常小的奇怪差异。对于上下文,我需要从具有奇怪和/或不可映射的 unicode 字符的 csv 文件中读取文件名,并将它们写入新的 csv 文件。对于它的价值,这对我有用:

s = '\u00e7\u00a3\u0085\u00e5\u008d\u0095' # csv freaks if you try to write this
s = repr(s.encode('utf-8', 'ignore'))[2:-1]

【讨论】:

【参考方案3】:

Python 的原始字符串只是告诉 Python 解释器应该将反斜杠解释为文字斜杠的一种方式。如果您读取用户输入的字符串,它们已经超过了它们可能是原始的点。此外,用户输入很可能按字面意思阅读,即“原始”。

这意味着翻译发生在其他地方。但是,如果您知道它会发生,为什么不转义反斜杠来解释它呢?

s = s.replace("\\", "\\\\")

(请注意,您不能将r"\" 用作“a raw string cannot end in a single backslash”,但我也可以将r"\\" 用于第二个参数。)

如果这不起作用,您的用户输入是出于某种神秘的原因来解释反斜杠,因此您需要一种方法来告诉它停止。

【讨论】:

这是我第一次看到“原始字符串不能以单个反斜杠结尾”。我没有意识到 Python 字符串解析是如此 hacky - 我认为 r 前缀意味着停止将反斜杠视为特殊,而是意味着输出两个字符而不是解释它们。 @MarkRansom 是的,f 字符串也只是字符串后处理,而不是实际的子解析器…… @MarkRansom 但是,否则如何在不关闭字符串文字的情况下添加"?这就是为什么它们不能以反斜杠结尾的原因,因为它将它解释为引号字符,所以字符串还没有结束。 @Anakhand 我刚刚假设您不能在原始字符串中加上引号。它仍然有点困难,因为你不能在它前面没有反斜杠。【参考方案4】:
a='\nu + \lambda + \theta'
d=a.encode('string_escape').replace('\\\\','\\')
print(d)
# \nu + \lambda + \theta

这表明nlt之前有一个反斜杠:

print(list(d))
# ['\\', 'n', 'u', ' ', '+', ' ', '\\', 'l', 'a', 'm', 'b', 'd', 'a', ' ', '+', ' ', '\\', 't', 'h', 'e', 't', 'a']

您的 GUI 出现了一些奇怪的现象。这是一个通过Tkinter.Entry 获取一些用户输入的简单示例。请注意,检索到的文本在 nlt 之前只有一个反斜杠。因此不需要额外的处理:

import Tkinter as tk

def callback():
    print(list(text.get()))

root = tk.Tk()
root.config()

b = tk.Button(root, text="get", width=10, command=callback)

text=tk.StringVar()

entry = tk.Entry(root,textvariable=text)
b.pack(padx=5, pady=5)
entry.pack(padx=5, pady=5)
root.mainloop()

如果您在输入框中键入\nu + \lambda + \theta,控制台将(正确)打印:

['\\', 'n', 'u', ' ', '+', ' ', '\\', 'l', 'a', 'm', 'b', 'd', 'a', ' ', '+', ' ', '\\', 't', 'h', 'e', 't', 'a']

如果您的 GUI 没有返回类似的结果(正如您的帖子所暗示的那样),那么我建议您研究解决 GUI 问题,而不是使用 string_escape 和字符串 replace

【讨论】:

如果是 python 来解释字符串,那就太好了。如果是 pandoc,它可能不起作用。你知道string_escape 还做了什么(除了反斜杠)吗?也许它做的太多了? @飞羊:文档说string_escape"produces a string that is suitable as string literal in Python source code."。 AFAIK,string_escape 影响反斜杠或反斜杠字符,仅此而已。也许我错了。如果它做得更多,我很乐意学习。 我知道的不比你多。很可能你是对的。但同样:如果发生解释的点吃掉了一些转义符(例如\s→` `),那么这将产生静默错误。他应该找到源头。 这不起作用,它不等同于原始字符串:将print(repr(r"\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\x93")) 的结果与print("\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\x93".encode('string_escape').replace('\\\\','\\')) 进行比较。【参考方案5】:

当您从 GUI 控件读取字符串时,它已经是一个“原始”字符串。如果您打印出字符串,您可能会看到反斜杠加倍,但这是 Python 显示字符串的一种人工制品;在内部仍然只有一个反斜杠。

>>> a='\nu + \lambda + \theta'
>>> a
'\nu + \\lambda + \theta'
>>> len(a)
20
>>> b=r'\nu + \lambda + \theta'
>>> b
'\\nu + \\lambda + \\theta'
>>> len(b)
22
>>> b[0]
'\\'
>>> print b
\nu + \lambda + \theta

【讨论】:

以上是关于如何转义通过用户输入收到的乳胶代码?的主要内容,如果未能解决你的问题,请参考以下文章

xss 防止攻击,恶意用户将输入的信息当成html或js代码执行,办法是将用户输入的信息改为text格式,或特殊符号转义

SQL 注入中的“参数化查询/准备语句”如何比转义用户输入更好

如何安全地为 bigquery 节点插入转义用户输入?可以在 bigquery.insert 节点库上使用参数化查询吗?

JS实现HTML标签转义及反转义

表单中用户输入"&lt"等转义字符,保存后数据库是原文保存的,但是查看的时候显示的是"<",如何是的&lt;字符在网页原样显示出来。(代码

SQL注入-预防