正则表达式与之前匹配的东西不匹配

时间:2014-06-22 00:31:37

标签: ruby regex chess

作为a question I asked earlier today的一部分,我的目标是验证车上用国际象棋表示法可以做出的所有动作。

这包括:

  • 字母R
  • 可选的消歧,问题的根源(稍后详细讨论)
  • 表示已进行捕获的可选x
  • 车移动的方格(国际象棋中的列[“文件”]字母a-h,行[“rank”]编号为1-8)

无视消歧,我们有简单的

/Rx?[a-h][1-8]/

消歧

经常发生两辆车可以移动到一个正方形,一个可以。发生这种情况时,使用消除歧义的字母或数字。因此,如果两个车辆在d3和h5上,而h5上的那个车道在d5上,则会写为Rhd5。同样地,当另一辆车在d1上时,d8上的车辆移动到d3 R8d3

文件优先于排名。在第一个示例中,如果d3上的车辆移至d5,则可以将其消除歧义为R3d5Rdd5。只有后者是正确的。

对车辆歧义消除的限制是:

  • 任何字母都可用于文件消歧,
  • 任何数字都可用于排名消歧,但移动到的方格数不能为1或8(R3d1无效,因为文件优先于排名,应为Rdd1 ),它的数字不能与正方形的数字相同(R3d3也无效)

考虑到上述情况,我构建了这个:

/R([a-h]?x?[a-h][1-8]|([1-8])x?[a-h][2-7&&[^\1]])/

问题在于最后一个字符[2-7&&[^\1]]。 Ruby从字面上解释[^\1],就像\1之外的所有字符一样。如果我尝试将\ 1置于括号([2-7&&[^]\1])之外,Ruby会抱怨没有元素的字符类。如果我使用永远不会发生的任意占位符,比如“z”([2-7&&[^z]\1]),它就不起作用(我无法解释原因)

那么我如何使用分组来匹配之前匹配的内容呢?

1 个答案:

答案 0 :(得分:2)

你的问题冗长密集,所以我将解决核心问题并让你实施这项技术:

  

如何使用分组与之前匹配的内容不匹配?

我们将一步一步地进行。以下不是一个确切的国际象棋范例,而是一个如何实现你想要的例子。

  1. 假设我想要一个匹配字母a到h的字符串。我的正则表达式是^[a-h]$
  2. 接下来我要匹配数字和短划线。我的正则表达式变为^[a-h][0-9]-$
  3. 接下来我想要匹配一封信,但不是我们之前匹配的那封信。我的正则表达式变为^([a-h])[0-9]-(?!\1)[a-h]$,其中([a-h])捕获到第1组的第一个字母,负向前瞻(?!\1)断言后面的内容不是第1组匹配的内容(即,这不是那封信。)
  4. 让我们为余额添加最后一位数:^([a-h])[0-9]-(?!\1)[a-h][0-9]$。这将匹配a1-b2但不匹配a1-a2
  5. 如果您有任何疑问,请与我们联系。

    <强>参考