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