Sprache を利用してセクション記号と複数のキー名と値を抽出するパーサーを作成する - C#
Sprache を利用してセクション記号と複数のキー名と値を抽出するパーサーのコードを紹介します。
プログラム
UI
下図のUIを作成します。複数行のテキストボックスを2つ、Buttonを1つ配置します。
コード
下記のコードを記述します。[button1]のClickイベントを実装しています。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sprache;
namespace SimpleSprache
{
public partial class FormSectionParse : Form
{
public class MySection
{
public string id;
public string name;
public IEnumerable<MyItem> myitems;
public MySection(string mid, string mname, IEnumerable<MyItem> mmyitems)
{
id = mid;
name = mname;
myitems = mmyitems;
}
}
public class MyItem
{
public string key;
public string value;
public MyItem(string mkey, string mvalue)
{
key = mkey;
value = mvalue;
}
}
public static readonly Parser<string> p_key = Parse.Letter.AtLeastOnce().Text().Token();
public static readonly Parser<string> p_value = (from open in Parse.Char('"')
from content in Parse.CharExcept('"').Many().Text()
from close in Parse.Char('"')
select content).Token();
public static readonly Parser<MyItem> p_key_value = from lk in p_key
from lv in p_value
select new MyItem(lk, lv);
public static readonly Parser<MySection> section = from id in p_key
from title in p_value
from lbracket in Parse.Char('[').Token()
from key_value_s in p_key_value.Many()
from rbracket in Parse.Char(']').Token()
select new MySection(id, title, key_value_s);
public FormSectionParse()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string input = textBox1.Text;
MySection section_item = section.Parse(input);
textBox2.Text = string.Format("{0} : {1}\r\n", section_item.id, section_item.name);
textBox2.Text += "-----\r\n";
foreach (MyItem m in section_item.myitems) {
textBox2.Text += string.Format("{0} : {1}\r\n", m.key, m.value);
}
}
}
}
解説
メインのパーサーのコードは下記になります。
id title
[
key1 value1
key1 value1
...
keyn valuen
]
の形式をパージングするコードです。複数個の要素を抽出する箇所は Many() メソッドを記述し複数の要素を検出できるようにします。
public static readonly Parser<MySection> section = from id in p_key
from title in p_value
from lbracket in Parse.Char('[').Token()
from key_value_s in p_key_value.Many()
from rbracket in Parse.Char(']').Token()
select new MySection(id, title, key_value_s);
p_key_value部分は下記の記述になっており、key と value の組をパージングするコードになっています。
public static readonly Parser<MyItem> p_key_value = from lk in p_key
from lv in p_value
select new MyItem(lk, lv);
パーサーの結果はMySectionオブジェクトで取得されます。MySectionオブジェクト内のid, nameをテキストボックスに表示します。また、MySectionオブジェクト内のmyitemsには複数のMyItemオブジェクトが格納されていますので、foreachループでMyItemsオブジェクトのkeyとvalueのペアをテキストボックスに表示します。
string input = textBox1.Text;
MySection section_item = section.Parse(input);
textBox2.Text = string.Format("{0} : {1}\r\n", section_item.id, section_item.name);
textBox2.Text += "-----\r\n";
foreach (MyItem m in section_item.myitems) {
textBox2.Text += string.Format("{0} : {1}\r\n", m.key, m.value);
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
上部のテキストボックスに下記の文字列を入力します。
Item "お気に入り"
[
Penguin "Jump"
Duck "Swim"
Owl "Sleep"
]
[button1]をクリックすると結果が下記のテキストボックスに表示されます。id, title部分とセクション内部のkey, value の複数のペアが取り出せていることが確認できます。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用