问题
由于不时需要在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)
谢谢