はじめに
正規表現の勉強としてタイトルにある通りのことをします。上の文字列を下のように変換するのが目的です。1+S5n1/6gk1/p2p1+B1pl/2p3s1p/1p4pN1/2PPp3P/PP1G2+bP1/1KGS1+r3/LN6L w GL2Prsn2p 102
後手の持駒:飛 銀 桂 歩二 | ・ 全 ・ ・ ・ ・ ・v桂 ・| | ・ ・ ・ ・ ・ ・v金v玉 ・| |v歩 ・ ・v歩 ・ 馬 ・v歩v香| | ・ ・v歩 ・ ・ ・v銀 ・v歩| | ・v歩 ・ ・ ・ ・v歩 桂 ・| | ・ ・ 歩 歩v歩 ・ ・ ・ 歩| | 歩 歩 ・ 金 ・ ・v馬 歩 ・| | ・ 玉 金 銀 ・v龍 ・ ・ ・| | 香 桂 ・ ・ ・ ・ ・ ・ 香| 先手の持駒:金 香 歩二 後手番
最終的にはSFEN文字列が複数書かれたテキストファイルから行数分のKIFファイルを作成できるようにしました。
「ShogiGUI」で動作確認済みです。
使い方
Pythonスクリプトが書かれたファイルを「sfen_converter.py」とします。SFEN文字列が複数書かれたテキストファイルを「sfen.txt」とします。
以下の1行を実行するだけです。
python sfen_converter.py sfen.txt
これでたくさんのKIFファイルが作成されます。
Pythonスクリプト
import re import sys koma_convert = { '+p':'vと', '+l':'v杏', '+n':'v圭', '+s':'v全', '+r':'v龍', '+b':'v馬', '+P':' と', '+L':' 杏', '+N':' 圭', '+S':' 全', '+R':' 龍', '+B':' 馬', 'p':'v歩', 'l':'v香', 'n':'v桂', 's':'v銀', 'g':'v金', 'k':'v玉', 'r':'v飛', 'b':'v角', 'P':' 歩', 'L':' 香', 'N':' 桂', 'S':' 銀', 'G':' 金', 'K':' 玉', 'R':' 飛', 'B':' 角', '0':' ・' } mochigoma_convert = { '18':'十八', '17':'十七', '16':'十六', '15':'十五', '14':'十四', '13':'十三', '12':'十二', '11':'十一', '10':'十', '9':'九', '8':'八', '7':'七', '6':'六', '5':'五', '4':'四', '3':'三', '2':'二', 'p':'歩', 'l':'香', 'n':'桂', 's':'銀', 'g':'金', 'r':'飛', 'b':'角', 'P':'歩', 'L':'香', 'N':'桂', 'S':'銀', 'G':'金', 'R':'飛', 'B':'角', } inputFile = sys.argv[1] with open(inputFile, 'r') as f: all_sfen = [x.strip() for x in f.readlines()] for line_num, sfen in enumerate(all_sfen): sfen_split = sfen.split(' ') kyokumen = sfen_split[0] teban = sfen_split[1] mochigoma = sfen_split[2] for i in range(1, 10): kyokumen = kyokumen.replace(str(i), '0'*i) for key, value in koma_convert.items(): kyokumen = kyokumen.replace(key, value) each_lines = [('|' + each_line + '|') for each_line in kyokumen.split('/')] mochigoma_sente = [] mochigoma_gote = [] while(mochigoma != ''): m = re.match(r'([0-9]+)([a-z|A-Z])', mochigoma) if(m != None): mochigoma = mochigoma.replace(m.group(), '') if(m.group().isupper()): mochigoma_sente.append(''.join(m.groups()[::-1])) else: mochigoma_gote.append(''.join(m.groups()[::-1])) m = re.match(r'[a-z|A-Z]', mochigoma) if(m != None): mochigoma = mochigoma.replace(m.group(), '') if(m.group().isupper()): mochigoma_sente.append(m.group()) else: mochigoma_gote.append(m.group()) sente_string = ' '.join(mochigoma_sente) gote_string = ' '.join(mochigoma_gote) for key, value in mochigoma_convert.items(): sente_string = sente_string.replace(key, value) gote_string = gote_string.replace(key, value) outputFile = 'KIF_%d.kif'%line_num with open(outputFile, 'w', encoding='cp932') as f: f.write('後手の持駒:') if(gote_string==''): f.write('なし') else: f.write(gote_string) f.write('\n') f.write('\n'.join(each_lines)) f.write('\n') f.write('先手の持駒:') if(sente_string==''): f.write('なし') else: f.write(sente_string) if(teban=='w'): f.write('\n') f.write('後手番')
注意点
Pythonは3.7以降を使用して下さい。それ以前のPythonでは辞書の順序がばらばらになるようです。例えば「18」を「十八」に変換するような場合に辞書の順序が重要になります。