问题
在此处和那里不得不包含一些JavaScript、XML和HTML在我的Clojure代码中时,转义引号可能会很麻烦且容易出错。这同样适用于脚本编写和运行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)
感谢您