问题
虽然在我的 Clojure 代码中这里那里不得不包含一些 JavaScript、XML 和 HTML,但是经常不得不转义引号,这会相当讨厌且容易出错。当在编写脚本和运行 shell 命令时也是如此,你可能会进入复杂的转义场景。
解决方案
添加一个字符串字面量,可以适应含有任何类型字符串,而不需要转义。
建议
文本块
某些其他语言提供一种称为文本块的特性,您可以使用三引号或更多引号在其中编写字符串,其中允许所有字符出现
(println """
This " is allowed,
and no need to escape it.
"""
文本块通常具有附加功能,例如,第一个和最后一个换行符不是字符串的一部分。并且三引号在源代码中的位置界定引号中行的开始。因此,上面的代码打印
This " is allowed,
and no need to escape it.
而不是
This " is allowed,
and no need to escape it.
虽然文本块在视觉上很整洁,因为它们在源代码中具有很好的对齐。但是它们依赖于空白,而 Clojure 到现在仍然是一个不依赖空白语言,这意味着空白无关紧要。我认为最好保持这种方式。因此,以下两个建议。
原始字符串
有时没有“块”功能的文本块被称为原始字符串字面量
(println """This " is allowed,
and no need to escape it.
Also support multi-line, but
not the "block" style of text blocks.""")
因此
(println """
This " is allowed,
and no need to escape it.
"""
打印
This " is allowed,
and no need to escape it.
与文本块不同。
如果您需要三引号,只需将分隔符改为四个引号
""""This """ is now allowed as well.""""
原始字符串的问题在于,如果您使用双引号作为分隔符
""This is a raw " string!""
但想要您的单引号在开始或结束位置
"""{{hello}}"""
我想要以下字符串: "{{hello}}"
,而不是 {{hello}}
,但原始字符串不能把这两者区分开来,因为它现在认为这是一个三引号分隔符。
一个解决方案是允许在开始或结束处使用转义引号
""\"{{hello}}\"""
但不能在中间使用
""\"{{he\llo}}\"""
因此,这个字符串是: "{{he\llo}}"
所以转义字符 \
可以在任何位置出现,但如果后跟引号则不在开始处,以及如果后跟引号则不在结尾处。
我仍然找不到这个理想。规则太多,仍然有需要转义的情况。
未转义字符串(我最喜欢的)
这里的想法是允许任何字符串用作分隔符。因此,对于内部嵌套的任何可能的Clojure代码字符串,我们总能找到一个不包含它的字符串用作分隔符。
假设添加了阅读宏 #text。它期望以下形式是一个普通字符串,该字符串告诉它下面的表达到读取使用的分隔符
(println #text "|" |"{{hello}}"|)
将打印
"{{hello}}"
#text的第一个参数告诉它以下原始字符串的分隔符是什么。这样,你绝对不需要在原始字符串中使用转义序列。对于任何给定的字符串,你都可以找到一个不包含它的分隔符字符串来正确处理它。
关于这种方法的疯狂想法,我只是随便说出来,如果你使用足够随机的字符串作为分隔符,这可能是一种奇怪的防止注入方法
(println #text "xIBgdSl4TCCOIdqdMu9G" xIBgdSl4TCCOIdqdMu9G
Can't nobody guess the delimiter to escape the string context :p
xIBgdSl4TCCOIdqdMu9G)
谢谢