问题
在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代码中的字符串,我们总能找到不在其内的字符串用作分隔符。
假设增加了 readline 宏 #text。该宏期望以下形式是一个普通字符串,用于告诉 readline 宏读取以下形式的分隔符。
(println #text "|" |"{{hello}}"|)
将会打印
"{{hello}}"
#text 的第一个参数告诉它下面的原始字符串的分隔符是什么。这样,你绝对不必在原始字符串中插入转义序列。对于任何给定的字符串,你可以找到一个不包含该字符串分隔符的字符串来正确处理它。
关于这种方法的一个疯狂的想法,只是随便说说,那就是如果你使用足够随机化的字符串作为分隔符,这可能是一种奇怪的注入攻击防护方法。
(println #text "xIBgdSl4TCCOIdqdMu9G" xIBgdSl4TCCOIdqdMu9G
Can't nobody guess the delimiter to escape the string context :p
xIBgdSl4TCCOIdqdMu9G)
谢谢