问题
既然我必须在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)
谢谢