我正在编写一个应该能够读取和解析国际象棋移动的程序(SAN )。
下面是一个可能被接受的动作的例子:
e4
Nf3
Nbd2
Nb1c3
R1a3
d8=Q
exd5
Nbxd2
...
Run Code Online (Sandbox Code Playgroud)
我首先编写了NFA,然后将其转换为语法,然后将其转换为正则表达式。
按照我的惯例,这就是它的样子
pln + plxln + plnxln + plnln + plln + pxln + lxln=(B+R+Q+N) + lxln + lnxln=(B+R+Q+N) + lnxln + lnln=(B+R+Q+N) + lnln + ln=(B+R+Q+N) + ln + pnxln + pnln
Run Code Online (Sandbox Code Playgroud)
在哪里:
p是 set 的一个字符{B,R,Q,N,K}(或认为它是(B+R+Q+N+K)=[BRQNK]
l是[a-h]区间中的一个字符(区分大小写)
n是[1-8]区间中的一个数
+代表联合操作......如果我没猜错的话,(B+R+Q+N)是[BRQN]使用正则表达式的编程语言。
= 只是一个普通字符......在国际象棋移动中它用于促销(例如e8 = Q)
x 也是一个普通的角色……当你在那个位置移动你的棋子时,你正在拿走对手的棋子。
(/ ): 就像数学一样
我尝试将第一部分解析pln为:[BRQN][a-h][1-8]在在线 Java 正则表达式测试器中,并为类似Nf3. 我不太了解如何为复合表达式(如pln+plxln)做联合操作……另外,我如何标记正则表达式的一部分,以便在检测到它时获得所有信息?我试图阅读有关它的文档,但没有弄清楚。
有什么建议吗?
您的符号+中的 是|在正则表达式中。所以你可以使用正则表达式
[BRQNK][a-h][1-8]|[BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8]|[BRQNK][a-h][1-8][a-h][1-8]|[BRQNK][a-h][a-h][1-8]|[BRQNK]x[a-h][1-8]|[a-h]x[a-h][1-8]=(B+R+Q+N)|[a-h]x[a-h][1-8]|[a-h][1-8]x[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]x[a-h][1-8]|[a-h][1-8][a-h][1-8]=(B+R+Q+N)|[a-h][1-8][a-h][1-8]|[a-h][1-8]=(B+R+Q+N)|[a-h][1-8]|[BRQNK][1-8]x[a-h][1-8]|[BRQNK][1-8][a-h][1-8]
Run Code Online (Sandbox Code Playgroud)
显然,这有点难看。我可以想到两种可能的方法来让它变得更好:
COMMENTS标志,您可以添加空格。[BRQNK][a-h]x[a-h][1-8]|[BRQNK][a-h][1-8]x[a-h][1-8]可以重写为[BRQNK][a-h][1-8]?x[a-h][1-8].我还知道 java 中没有的另一项改进。(也许不是很多语言,但你可以在 Perl 中做到这一点。)子表达式(?1)(同样(?2)等)有点像\1,只不过它不是匹配与第一个捕获组匹配的确切字符串,而是匹配可能具有的任何字符串与该捕获组匹配。换句话说,相当于把捕获组重新写出来了。因此,您可以(在 Perl 中)将第一个替换为[BRQNK],([BRQNK])然后将所有后续出现的替换为(?1)。
| 归档时间: |
|
| 查看次数: |
1224 次 |
| 最近记录: |