我怎样才能在 Scala 中将国际象棋棋子与字符串分开?

How could I separate Chess pieces from a string in Scala?

我有关于棋子的字符串格式的信息,例如:"Ka5Qb3a8b7",其中 "Ka5" 代表 a5 中的 King,"Qb3" 代表 b3 中的 Queen 和 "a8" 对于a8中的士兵。所以如果''那么士兵。

我怎样才能将每一部分分开,以便稍后将它们放入各自的对象中?我想我可以遍历每个索引并将它们匹配到不同的情况,并根据是否是士兵跳过 1 或 2 个后续字符。但是,如果存在这种方法,我更喜欢更短、更易读的代码。

我首先想到的是将 3 个大小分组,但显然不可能让士兵只拿 2 个字母。我正在使用 Scala。

正则表达式模式可以做到。

"[A-Z]?[a-z]\d".r.findAllIn("Ka5Qb3a8b7").toList
//res0: List[String] = List(Ka5, Qb3, a8, b7)

另一种选择是使匹配更具体一些,列出所有可用的 upper/lowercase 字符和数字,其中大写字符位于可选字符 class [KQNBR]? 中,使用问号.

"[KQNBR]?[a-h][1-8]".r.findAllIn("Ka5Qb3a8b7").toArray
res0: Array[String] = Array(Ka5, Qb3, a8, b7)

如果字符串始终采用相同的格式,使用 split with lookarounds 也可以。

"Ka5Qb3a8b7".split("(?<=\d)(?=[A-Za-z])")
res0: Array[String] = Array(Ka5, Qb3, a8, b7)

在 Scala 2.13 中你可以使用 List.unfold:

val chess = "Ka5Qb3a8b7"
List.unfold(chess) { remainingMoves =>
  Option.when(remainingMoves.nonEmpty) {
    val (currentMove, remaining) = remainingMoves.span(!_.isDigit)
    (currentMove + remaining.head, remaining.tail)
  }
}

结果是:

List(Ka5, Qb3, a8, b7)

代码 运行 Scastie.