用于国际象棋棋步解析的Python正则表达式

问题描述 投票:0回答:1

应考虑以下条件:

  1. 需要给出目标方格的全长(a-h 和 1-8 棋盘坐标) 例外情况是易位,它以传统的易位符号表示(

    O-O
    O-O-O
    )。

  2. 填写诸如

    takes
    goes to
    之类的单词是可选的。

  3. 如果指定了攻击棋子的坐标,则
  4. on
    是可选的,否则
    on
    没有任何意义。

  5. 如果写出片段或填充词(

    Rook
    goes to
    king
    captures
    ),这些将需要通过空格进行缓冲。如果单词位于输入字符串的开头或结尾,则也不需要空格。如果该片段缩写为单个字符,则不需要后面的空格。 (
    Nf3
    -> 不需要空格;
    knight f3
    -> 需要空格;
    Nxd4
    -> 不需要空格;
    N takes d4
    ->
    takes
    两侧都需要空格)

  6. 如果该棋子是缩写的,则需要大写字母以区别于棋盘坐标(

    B
    表示主教和
    b
    坐标)。

  7. 如果攻击棋子的两个坐标都给出了(

    e2e4
    Pe2e4
    ),或者该棋子是棋子,则不必给出该棋子(
    e4
    Pe4
    )。

  8. 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)?'

有很多双空格,而需要的地方却没有空格。 我确信有更好的方法来做到这一点......

python regex
1个回答
0
投票

尝试(在自由间距模式下):

^ # 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

© www.soinside.com 2019 - 2024. All rights reserved.