应考虑以下条件:
需要给出目标方格的全长(a-h 和 1-8 棋盘坐标) 例外情况是易位,它以传统的易位符号表示(
O-O
,O-O-O
)。
填写诸如
takes
或goes to
之类的单词是可选的。
on
是可选的,否则on
没有任何意义。
如果写出片段或填充词(
Rook
、goes to
、king
、captures
),这些将需要通过空格进行缓冲。如果单词位于输入字符串的开头或结尾,则也不需要空格。如果该片段缩写为单个字符,则不需要后面的空格。
(Nf3
-> 不需要空格;knight f3
-> 需要空格;Nxd4
-> 不需要空格;N takes d4
-> takes
两侧都需要空格)
如果该棋子是缩写的,则需要大写字母以区别于棋盘坐标(
B
表示主教和b
坐标)。
如果攻击棋子的两个坐标都给出了(
e2e4
是Pe2e4
),或者该棋子是棋子,则不必给出该棋子(e4
是Pe4
)。
Check 和 checkmate 是可选的,如果不缩写也需要用空格缓冲(是
Rd8+
、是 Rd8 check
、是 Rd8 +
、否 Rd8check
)。
输入示例:
Knight on g1 goes to f3
b captures a8 =q checkmate
Ra1e1+
rook 2 to f8 with check
O-O-O#
正则表达式的可能结构:
[Knight ][on ][g1][ to ][f3][ with check] -> 'Knight to f3' not possible!
[Knight][ on][ g1][ to ][f3][ with check] -> 'Ng1f3' not possible!
[Knight][ on ][g1][ to ][f3][ with check] -> 'Knight g1 to f3' not possible!
这就是我到目前为止所想出的:
r'(Knight|knight|N)?( on )?[a-h]?[1-8]?( to | takes | captures )?[a-h][1-8](Q|=Q| queen)?( check| checkmate)?'
有很多双空格,而需要的地方却没有空格。 我确信有更好的方法来做到这一点......
尝试(在自由间距模式下):
^ # start of string
(?: # list of moves
(?: # option 1; regular move
( # list of figures
[Kk]night|N|n|
[Bb]ishop|B|b|
[Rr]ook|R|r
# extend as needed
)
( # possible "from"s
(?:\ on\ )?
[a-h][1-8]
|
\ [1-8]
)?
( # possible "to" prefixes
\ (?:(?:goes\ )?to|takes|captures)\
)?
[a-h][1-8] # to
( # list of figures at destination
\
(?:
q|=q|Q|=Q|queen
# enrich as needed
)
)?
( # result of move
(?:\ with)\ check|\ checkmate|\+
)?
)# end regular move
|
(?:O-O\#) # option 2 casteling
|
(?:O-O-O\#) # option 3 long casteling
)
$
普通模式变为:
^(?:(?:([Kk]night|N|n|[Bb]ishop|B|b|[Rr]ook|R|r)((?:\ on\ )?[a-h][1-8]|\ [1-8])?(\ (?:(?:goes\ )?to|takes|captures)\ )?[a-h][1-8](\ (?:q|=q|Q|=Q|queen))?((?:\ with)\ check|\ checkmate|\+)?)|(?:O-O\#)|(?:O-O-O\#))$
参见:regex101