C# .NetCoreで、ボートレース結果の解析　前調査

# やらなきゃいけないこと
- 競争成績の内容を確認し、抽出方法を考えておく。

## 競争成績の取得
- ボートレース公式→データを調べる→競争成績→日付を選択すればダウンロードすることができる。一時期気合でDLしていたファイルが一通り存在しているため、今回はスクレイピングなどは行わない。時期にやる。

##フォーマット
- ファイル名：Kyymmdd.TXT(yy：実施年、mm：実施月、dd：実施日）
   例：K191001.TXT(2019年10月1日の競争成績一覧)

- 基本的な流れ（K191001.TXTを例にとってみる）
- 
```
STARTK
24KBGN
大　村［成績］     10/ 1      第６回夜の本命・波乱  第 5日

                            ＊＊＊　競走成績　＊＊＊

          第６回夜の本命・波乱決定戦　　　　　　　　　　　　

   第 5日          2019/10/ 1                             ボートレース大　村

               －内容については主催者発行のものと照合して下さい－

   [払戻金]       ３連単           ３連複           ２連単         ２連複
           1R  3-1-2    3360    1-2-3     260    3-1    1560    1-3     290
          ...略...
          12R  1-4-6    2010    1-4-6     810    1-4     530    1-4     390



   1R       一　般　　　                 H1800m  曇り  風  北西　 1m  波　  1cm
  着 艇 登番 　選　手　名　　ﾓｰﾀｰ ﾎﾞｰﾄ 展示 進入 ｽﾀｰﾄﾀｲﾐﾝｸ ﾚｰｽﾀｲﾑ 差し　　　
-------------------------------------------------------------------------------
  01  3 2841 吉　田　　　　稔 70   75  6.82   3    0.14     1.50.6
  ...略...
  06  5 3856 水　野　　暁　広 43   21  6.79   5    0.24      .  . 

        単勝     3         2150  
        複勝     3          170  1          120  
        ２連単   3-1       1560  人気     6 
        ２連複   1-3        290  人気     2 
        拡連複   1-3        170  人気     3 
                 2-3        140  人気     2 
                 1-2        120  人気     1 
        ３連単   3-1-2     3360  人気    12 
        ３連複   1-2-3      260  人気     1 


  2～12Rは省略
24KEND
22KBGN
...略
05KEND
FINALK
```

## 大まかな流れ
- レース結果以外の内容の取得
  - 開催場の取得
  - タイトルの取得
  - 開催日の取得
- 払戻金の取得
- レース結果の取得
  - レース結果（決まり手、気候、レース名など）
  - 各選手毎情報（着　登録番号　モーターなど）

情報量が増えるため、なるべく文字列でとらない方向で検討していく。

## レース結果以外の内容の取得
取得範囲はこの部分になる。

```
STARTK
24KBGN
大　村［成績］     10/ 1      第６回夜の本命・波乱  第 5日

                            ＊＊＊　競走成績　＊＊＊

          第６回夜の本命・波乱決定戦　　　　　　　　　　　　

   第 5日          2019/10/ 1                             ボートレース大　村
```

``24KBGN``の[24]はボートレース大村の開催場コードとなっており、ここでどこの開催場かわかる。
次の行の``` 10/ 1      第６回夜の本命・波乱  第 5日```で開催日と開催日目がわかる。
その次の行の``` 第６回夜の本命・波乱決定戦```で節間タイトルがわかる。

見た感じ、```String.split()```するよりも、以下の関数を作成して、取り出すほうが現実的だと思う。

```
        string StringExtraction(string src, int st, int count)
        {
            if (encSJIS == null)
                encSJIS = Encoding.GetEncoding("Shift_JIS");
            byte[] rtnBytes = new byte[count];
            var srcbytes = encSJIS.GetBytes(src);
            Array.Copy(srcbytes, st, rtnBytes, 0, count);
            return encSJIS.GetString(rtnBytes);
        }
```
第一引数から、行文字列、開始位置、文字数で取得する。
やっている作業はShift-JISのバイト型配列に変換→開始位置→から文字数分抜き出し、stringに戻す作業を行っている。幸い元のファイルの文字コードがShift-JISであるため、漢字は2文字カウントとすることで、扱いやすくできる。実際の文字数ではないため、テキストエディタで、文字数を確認しながら位置を確認していけばいい。

## 払戻金の取得
取得範囲はこの部分になる。

```
   [払戻金]       ３連単           ３連複           ２連単         ２連複
           1R  3-1-2    3360    1-2-3     260    3-1    1560    1-3     290
          ...略...
          12R  1-4-6    2010    1-4-6     810    1-4     530    1-4     390
```

左から、レース番号、３連単[組、配当]、３連複[組、配当]、２連単[組、配当]、２連複[組、配当]の順となっている。構成もシンプルであるため、```String.Split(' ', StringSplitOptions.RemoveEmptyEntries)```で簡単に分割が行えそうである。

しかし気づいてしまった。ここの情報には人気が記載されていない。
そのため、

```
        単勝     3         2150  
        複勝     3          170  1          120  
        ２連単   3-1       1560  人気     6 
        ２連複   1-3        290  人気     2 
        拡連複   1-3        170  人気     3 
                 2-3        140  人気     2 
                 1-2        120  人気     1 
        ３連単   3-1-2     3360  人気    12 
        ３連複   1-2-3      260  人気     1 
```

取得したほうがいい気がする。
いずれのレースも上記順番であるため、```String.Split(' ', StringSplitOptions.RemoveEmptyEntries)```で簡単に分割が行えそうである。
直前行の内容から、問題なくレース番号の紐づけも取得できそう。

## レース結果
```
   1R       一　般　　　                 H1800m  曇り  風  北西　 1m  波　  1cm
  着 艇 登番 　選　手　名　　ﾓｰﾀｰ ﾎﾞｰﾄ 展示 進入 ｽﾀｰﾄﾀｲﾐﾝｸ ﾚｰｽﾀｲﾑ 差し　　　
-------------------------------------------------------------------------------
  01  3 2841 吉　田　　　　稔 70   75  6.82   3    0.14     1.50.6
  ...略...
  06  5 3856 水　野　　暁　広 43   21  6.79   5    0.24      .  . 
```
```
1R       一　般　　　                 H1800m  曇り  風  北西　 1m  波　  1cm
```
この行で、該当レース番号と、結果、天気、風向、風力、の取得が行える。
構成もシンプルであるため、
```String.Split(' ', StringSplitOptions.RemoveEmptyEntries)```で
簡単に分割が行えそう。

```
着 艇 登番 　選　手　名　　ﾓｰﾀｰ ﾎﾞｰﾄ 展示 進入 ｽﾀｰﾄﾀｲﾐﾝｸ ﾚｰｽﾀｲﾑ 差し　
```
この行には、決まり手がスペース分割後の最終項に記載されているため、取得が必要である。
本行も```String.Split(' ', StringSplitOptions.RemoveEmptyEntries)```で
簡単に分割が行えそう。

```
01  3 2841 吉　田　　　　稔 70   75  6.82   3    0.14     1.50.6
```
この行が、各選手の情報になる。
着順、艇番、登録番号、選手名、ﾓｰﾀｰ、ﾎﾞｰﾄ、展示、進入、スタートタイミング、レースタイム
の順番に記載されている。
本例の場合は、シンプルな構成に見えるが、選手がFを切った場合や失格、欠場になった場合など、複雑なパターンが容易に想定されるので、
```String.Split(' ', StringSplitOptions.RemoveEmptyEntries)```関数を使用しての取り出しのほうがよさそう。レースタイムも、変な感じだし。おそらく欠場の場合も似たようになるでしょう。

## まとめ
本項では、データの表示内容のフォーマットを確認でき、文字列からデータの取り出し方に
関して検討を進めることができた。
次回は、実際のデータの取得と、取得データの分け方の検討について書きたいと思う。

次回
C# .NetCoreで、ボートレース結果の解析　構造検討
https://qiita.com/TamanegiTarao/items/04f43d96e50cb3eeaa03