问题
由于必须在 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)
感谢