Skip to content

教程——匹配规则入门

Yanbing Zhao edited this page Oct 1, 2018 · 4 revisions

以下的所有规则均以/ebi query开头。请保证使用者至少拥有epicbanitem.command.query权限。

我们先给自己一个骨粉:

/give @p minecraft:dye 1 15

现在我们输入/ebi query {} ,可以看到以下输出:

{
  id: "minecraft:dye",
  Damage: 15
}

很好。这说明{}这一规则成功匹配了这一物品。同时我们返回得到了这个物品的NBT(除物品数量外)。

{}是最简单的一条规则,代表匹配任何物品——你可以使用这一规则查看物品的NBT。

P.S.你可以使用不带任何参数的/ebi query命令以使用上一条指定的规则匹配物品。

匹配NBT标签属性

我们输入以下命令(注意大小写):

/ebi query {Damage: 15}

我们得到了和上面类似的输出:

{
  id: "minecraft:dye",
  Damage: 15
}

我们的{Damage: 15}规则成功匹配了物品的Damage属性,从而匹配了这一物品。由于我们使用的是HOCON,因此{Damage: 15}{Damage=15}是等价的。

如果我们输入下面的命令呢?

/ebi query {Damage: 0}

由于Damage属性的值是15,而不是我们在匹配规则中希望匹配到的0——因此除了一条提示信息外,什么都不会输出。

下面的命令也会成功匹配这一物品:

/ebi query {id: "minecraft:dye"}

同样,下面的命令无法成功匹配骨粉:

/ebi query {id: "minecraft:stone"}

匹配规则的组合

我们可以把两条匹配规则直接组合到一起,表示只有同时满足多条规则的物品才会匹配到:

/ebi query {id: "minecraft:dye", Damage: 15}

这代表匹配物品为minecraft:dye而且Damage为15的物品,这样就只会匹配骨粉了。

表示“与”的匹配规则很简单,但是表示“或”的话,我们需要用到一个名为$or的操作符:

/ebi query {"$or": [{id: "minecraft:stone"}, {Damage: 0}]}

这代表匹配了物品为minecraft:stone或者Damage为0的物品。

注意$or(以及后续出现的所有操作符)的两边,需要使用双引号括上。

我们还有一个名为$nor的操作符:

/ebi query {"$nor": [{id: "minecraft:stone"}, {Damage: 0}]}

这代表匹配了既不满足物品为minecraft:stone也不满足Damage为0的物品。

事实上我们还有$and操作符,不过不常用——以下两个命令是等价的:

/ebi query {id: "minecraft:dye", Damage: 15}
/ebi query {"$and": [{id: "minecraft:dye"}, {Damage: 15}]}

还有一个常用的操作符为$in,比如下面的命令:

/ebi query {Damage: {"$in": [0, 15]}}

这匹配所有Damage[0, 15]中的一个(也就是0或15)的物品。

匹配子NBT标签

接下来我们给自己一个几乎没有耐久却有着耐久III附魔的钻石镐:

/give @p minecraft:diamond_pickaxe 1 1561 {ench: [{lvl: 3s, id: 34s}], RepairCost: 1}

/ebi query {}后的结果是这样的:

{
  id: "minecraft:diamond_pickaxe", 
  tag: {
    ench: [
      0: {
        lvl: 3s, 
        id: 34s
      }
    ], 
    RepairCost: 1
  }, 
  Damage: 1561
}

我们使用以下命令匹配RepairCost为1:

/ebi query {"tag.RepairCost": 1}

注意,这和以下的命令不同:

/ebi query {tag: {RepairCost: 1}}

前者匹配的是tagRepairCost对应的值为1,而后者匹配的是tag下的标签和{RepairCost: 1}完全符合

还有一点需要注意的是:tag.RepairCost两边需要加上双引号,因为根据HOCON语法,{tag.RepairCost: 1}{tag: {RepairCost: 1}}等价。

我们称这种使用tag.RepairCost匹配一个标签里的另一个标签的方式为点语法。

匹配列表

列表对于匹配规则通常是透明的,比如:

/ebi query {"tag.ench": {lvl: 3s, id: 34s}}

这能够成功匹配物品,因为即使tag.ench是一个列表,但只要其中有一个元素能够匹配,整个匹配规则便能够匹配。这里的匹配规则精确地匹配了作为一个列表元素的标签。

如果想要精确地匹配某个列表中的元素,请使用下面的匹配方法:

/ebi query {"tag.ench.0": {lvl: 3s, id: 34s}}

0代表列表的第一个元素,1代表第二个,依此类推。因此下面的匹配规则便不能成功匹配:

/ebi query {"tag.ench.1": {lvl: 3s, id: 34s}}

使用正则表达式匹配字符串

开头和结尾均为/的字符串值将会被视为正则表达式,比如:

/ebi query {id: "/^minecraft:/"}

这将匹配所有原版物品,因为它们均以minecraft:开头。

由于正则表达式往往需要大量转义符,因此建议使用三个引号将正则表达式括起来,以避免多余的转义:

/ebi query {id: """/^minecraft:[a-zA-Z]+_pickaxe$/"""}

上面的匹配规则将会匹配所有的原版镐子。

基于MongoDB的匹配规则

读者如果对MongoDB有所了解,那么将会注意到EpicBanItem用到的所有规则,其实都是基于MongoDB的。EpicBanItem目前已经支持了大多数MongoDB的操作符和匹配规则,请参阅MongoDB的文档(https://docs.mongodb.com/manual/reference/operator/query/)以了解更多。

EpicBanItem目前支持的MongoDB的操作符有:

  • $eq$ne$gt$lt$gte$lte$in$nin:用于比较
  • $or$nor$and$not:用于匹配规则的逻辑运算
  • $size$all$elemMatch:用于匹配数组
  • $regex$options:用于正则表达式匹配
  • $where:用于JavaScript匹配

EpicBanItem目前独有的操作符有:

  • $tagType:和MongoDB的$type对应,只不过匹配的是NBT标签类型