问题
在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)
谢谢