sylqiuyifeng
本帖最后由 贰逼 于 2015-5-9 19:12 编辑

首先说明一下,这帖子并不是新手教程也不是适合新人阅读的教程,所以别再回复什么看不懂了,看起来好高大上之类的回复了

只是对一个重要的,在命令总中使用的机制——转义的探讨
这次是关于多重转义的发现


转义简介
转义:转变意义
转义最重要的功能就是告诉系统,双引号"究竟是属于哪一层的值的
为了避免系统混淆,值内所使用的引号需要转义,在格式要求严格的JSON中体现甚多
比如:
我需要tellraw显示"hello world"
而格式为
  1. /tellraw @a {text:"[值]"}
复制代码


那么为了在值的部分输入引号,我们需要使用:
  1. /tellraw @a {text:""hello world""}
复制代码


如果没有转义(\")的话
系统会认为命令是"
  1. /tellraw @a {text:""}
复制代码
这部分已经完结了text的值(空值),然后后面的全部不符合JSON格式
会出现
  1. 无效的json:Unterminated object at line 1 column 10
复制代码
的提示
这就是对转义的简单解释
一切都是系统蠢惹的祸,我们必须清清楚楚告诉他
"hello world"中的引号,属于第二层的引号(第一层是text部分的引号)
那样系统就不会搞乱


转义探讨
然而我们组内在探讨2b组长:关于原版内输入格式符§的发现
对于出现的\\\"疑惑不解
当初我只是以为是转义的另一个写法
事实证明了用\"会导致命令错误


错误示范
2b的发现很重要一步,就是通过设置牌子的CE,/blockdata某个命令方块,其中包含格式符的unicode,突破程序的限制
以下是例子(并不涉及到格式符部分,只是类似步骤的命令):
  1. /blockdata ~ ~1 ~ {Text1:"{text:"test",clickEvent:{action:run_command,value:"/blockdata 109 56 326 {Command:"say "hi""}"}}"}
复制代码
命令本意是想修改上方的牌子,让牌子拥有blockdata掉某个命令方块的CE,使命令变成/say "hi"
但效果变成了这个:

右键以后也没有效果


经过一轮排除测试后,发现问题出现在value部分的blockdata命令,还有里面的command NBT tag
虽然不采用规范化书写能够排除这个问题,但是本着探讨的心,对转义系统进行了研究
该命令最大的问题在于引号的层级和嵌套导致系统无法正确识别
我们发现,转义也是具有层级性
就是说,在已转义部分,或者说在一个值里面,还需要使用引号的话,那么必须进行二次转义
让系统不会混淆

我们来分析以上错误命令
  1. value:"/blockdata 109 56 326 {Command:"say "hi""}"
复制代码

问题出在这一块,value:\"\"部分没有问题,他在text1内,属于第一层转义,使用\"是正确的
问题在于Command:""部分,还有say "hi"部分的引号
Command后方的引号处在一层的value内,应该属于第二层
say "hi"同理,属于第三层
所以一概使用\"必然会出现错误


那么有着\\\"这个发现的前提下,我们发现了转义内转义的规律
每一次转义,都必须在已经出现的\和"前添加多一个\
所以第零层的"
第一层的是\"("前+\)(1个\)
第二层的是\\\"(基于第二层的\",添加多两个\)(3个\)
第三层的是\\\\\\\"(添加多4个\)(7个\)
如此类推
就是说,每一层的斜杠数量都是前面的2倍+1个
或者使用以下公式计算
  1. 2^n-1
复制代码
2的n次方-1个(n代表目前层)


按照这个规律来做的话,以上命令的正确写法为:
  1. /blockdata ~ ~1 ~ {Text1:"{text:"test",clickEvent:{action:run_command,value:"/blockdata 109 56 326 {Command:\\"say \\\\\\"hi\\\\\\"\\"}"}}"}
复制代码
value是第一层,用\"
command是第二层,用\\\“
say部分的引号是第三层,用\\\\\\\"
效果如下:


右键之后,目标命令方块内:




补充说明
最后一点要注意的是,并不是说引号内的引号一定就是下一层的
例如我要tellraw输出""hello world""
那么命令是
  1. /tellraw @a {text:"""hello world"""}
复制代码

而不是

  1. /tellraw @a {text:""\\"hello world\\"""}
复制代码
因为他们同属text的值内的引号,是第一层转义
所以同样使用\"系统就能识别了,反而第二个写法输出有误
变成了:




总结:
1.转义使用的\数量为:
  1. 2^n-1
复制代码
2的n次方-1个(n代表目前层)

2.同样层级下的转义使用同样数量的\

(终极吐槽:我看了看2b的命令,发现根本不需要多重转义……因为他是不规范格式邪教2333)
来自群组: Command Block Logic
2021.12 数据,可能有更多内容首先说明一下,这帖子并不是新手教程也不是适合新人阅读的教程,所以别再回复什么看不懂了,看起来好高大上之类的回复了


只是对一个重要的,在命令总中使用的机制——转义的探讨
这次是关于多重转义的发现


转义简介
转义:转变意义
转义最重要的功能就是告诉系统,双引号"究竟是属于哪一层的值的
为了避免系统混淆,值内所使用的引号需要转义,在格式要求严格的JSON中体现甚多
比如:
我需要tellraw显示"hello world"
而格式为

代码:

  1. /tellraw @a {text:"[值]"}



那么为了在值的部分输入引号,我们需要使用:

代码:

  1. /tellraw @a {text:""hello world""}



如果没有转义(\")的话
系统会认为命令是"

代码:

  1. /tellraw @a {text:""}
这部分已经完结了text的值(空值),然后后面的全部不符合JSON格式
会出现

代码:

  1. 无效的json:Unterminated object at line 1 column 10
的提示
这就是对转义的简单解释
一切都是系统蠢惹的祸,我们必须清清楚楚告诉他
"hello world"中的引号,属于第二层的引号(第一层是text部分的引号)
那样系统就不会搞乱


转义探讨
然而我们组内在探讨2b组长:关于原版内输入格式符§的发现
对于出现的\\\"疑惑不解
当初我只是以为是转义的另一个写法
事实证明了用\"会导致命令错误


错误示范
2b的发现很重要一步,就是通过设置牌子的CE,/blockdata某个命令方块,其中包含格式符的unicode,突破程序的限制
以下是例子(并不涉及到格式符部分,只是类似步骤的命令):

代码:

  1. /blockdata ~ ~1 ~ {Text1:"{text:"test",clickEvent:{action:run_command,value:"/blockdata 109 56 326 {Command:"say "hi""}"}}"}
命令本意是想修改上方的牌子,让牌子拥有blockdata掉某个命令方块的CE,使命令变成/say "hi"
但效果变成了这个:

右键以后也没有效果


经过一轮排除测试后,发现问题出现在value部分的blockdata命令,还有里面的command NBT tag
虽然不采用规范化书写能够排除这个问题,但是本着探讨的心,对转义系统进行了研究
该命令最大的问题在于引号的层级和嵌套导致系统无法正确识别
我们发现,转义也是具有层级性
就是说,在已转义部分,或者说在一个值里面,还需要使用引号的话,那么必须进行二次转义
让系统不会混淆


我们来分析以上错误命令

代码:

  1. value:"/blockdata 109 56 326 {Command:"say "hi""}"

问题出在这一块,value:\"\"部分没有问题,他在text1内,属于第一层转义,使用\"是正确的
问题在于Command:""部分,还有say "hi"部分的引号
Command后方的引号处在一层的value内,应该属于第二层
say "hi"同理,属于第三层
所以一概使用\"必然会出现错误


那么有着\\\"这个发现的前提下,我们发现了转义内转义的规律
每一次转义,都必须在已经出现的\和"前添加多一个\
所以第零层的"
第一层的是\"("前+\)(1个\)
第二层的是\\\"(基于第二层的\",添加多两个\)(3个\)
第三层的是\\\\\\\"(添加多4个\)(7个\)
如此类推
就是说,每一层的斜杠数量都是前面的2倍+1个
或者使用以下公式计算

代码:

  1. 2^n-1
2的n次方-1个(n代表目前层)


按照这个规律来做的话,以上命令的正确写法为:

代码:

  1. /blockdata ~ ~1 ~ {Text1:"{text:"test",clickEvent:{action:run_command,value:"/blockdata 109 56 326 {Command:\\"say \\\\\\"hi\\\\\\"\\"}"}}"}
value是第一层,用\"
command是第二层,用\\\“
say部分的引号是第三层,用\\\\\\\"
效果如下:



右键之后,目标命令方块内:





补充说明
最后一点要注意的是,并不是说引号内的引号一定就是下一层的
例如我要tellraw输出""hello world""
那么命令是

代码:

  1. /tellraw @a {text:"""hello world"""}

而不是


代码:

  1. /tellraw @a {text:""\\"hello world\\"""}
因为他们同属text的值内的引号,是第一层转义
所以同样使用\"系统就能识别了,反而第二个写法输出有误
变成了:





总结:
1.转义使用的\数量为:

代码:

  1. 2^n-1
2的n次方-1个(n代表目前层)


2.同样层级下的转义使用同样数量的\


(终极吐槽:我看了看2b的命令,发现根本不需要多重转义……因为他是不规范格式邪教2333)

乾.坤
cbl神教逆天233

simon3000
请不要在论坛继续损害他人的自尊心和脑子了
干得漂亮

pca006132
拜见大神{:10_512:},小弟想问问
是不是json里面所有的转移都是同一层级的,只是NBT里面的需要多层转移?
我路过所以就水个回复了233333{:10_496:}

C-青皮君
\\\\\\\\\\\\\\\"2\\\\\\\"333\\\"333\"3\"333\\\"333\\\\\\\"333\\\\\\\\\\\\\\\\"

simon3000
今天发了好多东西?
高产啊

貌似和我以前再用Bat输出另外一个文档的时候不知道怎么输出"(好像)的类似问题的解决办法

ufof
先让我在读几遍

sylqiuyifeng
pca006132 发表于 2015-5-9 17:42
拜见大神,小弟想问问
是不是json里面所有的转移都是同一层级的,只是NBT里面的需要多层转移?
...

……
反正就是如果是一个值内套一个值的话
就是+一层的转义

sylqiuyifeng
本帖最后由 贰逼 于 2015-5-9 19:15 编辑
simon3000 发表于 2015-5-9 17:43
今天发了好多东西?
高产啊

233
其实我这探讨是受2b帖子的启发
但我回首一看的时候
发现不规范书写其实根本不需要这科技……
结果就是无中生有了的感觉

lzs1234
系统本来就蠢…(有人说这是为了系统准确…)
在value里打带引号的NBT真是令人发疯…
(为什么这么多人看不懂,很简单嘛…)

sylqiuyifeng
lzs1234 发表于 2015-5-9 18:27
系统本来就蠢…(有人说这是为了系统准确…)
在value里打带引号的NBT真是令人发疯…
(为什么这么多人看不 ...

这就是这次探讨出现的原因了

huanghongxun
MC的代码比较蠢。。
写的转义比较坑
一切都是Dinnerbone的锅

sylqiuyifeng
huanghongxun 发表于 2015-5-9 18:41
MC的代码比较蠢。。
写的转义比较坑
一切都是Dinnerbone的锅

1,3,7,15,31个/
想想都觉得恐怖……
虽然我觉得能用到7个的时候已经是很过分的命令了233

huanghongxun
sylqiuyifeng 发表于 2015-5-9 18:41
1,3,7,15,31个/
想想都觉得恐怖……
虽然我觉得能用到7个的时候已经是很过分的命令了233 ...

mc指令长度好像是有限制的

下一页 最后一页