Sprache を利用してキー名と値を抽出するパーサーを作成する - C#
Sprache を利用してキー名と値を抽出するパーサーのコードを紹介します。
プログラム1 (2つの値の抽出)
UI
下図のUIを作成します。Windows Formに複数行のTextBoxを2つ、Buttonを1つ配置します。
コード
下記のコードを記述します。
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 FormKeyValueParse : Form
{
public class MyItem
{
public string key;
public string value;
public MyItem(string mkey, string mvalue)
{
key = mkey;
value = mvalue;
}
}
public static readonly Parser<MyItem> parse = from lk in Parse.Letter.AtLeastOnce().Text().Token()
from lv in Parse.Letter.AtLeastOnce().Text().Token()
select new MyItem(lk, lv);
public FormKeyValueParse()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string input = textBox1.Text;
MyItem item = parse.Parse(input);
textBox2.Text = string.Format("{0} : {1}", item.key, item.value);
}
}
}
解説
下記のコードにより、空白またはタブで区切られた2語を抽出します。抽出した語はMyItemオブジェクトのインスタンスとして返します。
public static readonly Parser<MyItem> parse = from lk in Parse.Letter.AtLeastOnce().Text().Token()
from lv in Parse.Letter.AtLeastOnce().Text().Token()
select new MyItem(lk, lv);
パーサーにより入力された文字列をパージングします。Parseメソッドは、MyItemオブジェクトを返します。戻り値の値をテキストボックスに表示します。
private void button1_Click(object sender, EventArgs e)
{
string input = textBox1.Text;
MyItem item = parse.Parse(input);
textBox2.Text = string.Format("{0} : {1}", item.key, item.value);
}
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
上部のテキストボックスにパージングする文字列を入力します。今回は"Penguin Jump"の文字列を入力します。
[button1]をクリックします。下部のテキストボックスに、"Penguin"と"Jump"の値がコロンで区切られて表示されます。keyとvalueがそれぞれ抽出できていることが確認できます。
補足
ちなみに、valueの部分を数値にした場合、語句とみなされないため、例外が発生します。
Sprache.ParseException が発生します。
プログラム2 (値が「"」で囲まれている2つの値の抽出)
続いて、値が「"」で囲まれている場合の抽出コードを紹介します。
UI
下図のUIを作成します。Windows Formに複数行のTextBoxを2つ、Buttonを2つ配置します。Buttonは2つ配置されていますが、[button2]のみを利用します。
コード
下記のコードを記述します。(button2のクリックイベントを実装します。)
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 FormKeyValueParse : Form
{
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> parse2 = from lk in p_key
from lv in p_value
select new MyItem(lk, lv);
public FormKeyValueParse()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
string input = textBox1.Text;
MyItem item = parse2.Parse(input);
textBox2.Text = string.Format("{0} : {1}", item.key, item.value);
}
}
}
解説
下記のコードは、先の例の空白またはタブで区切られた2語を抽出するパーサーと似た形式の式です。ただし、"Parse.Letter.AtLeastOnce().Text().Token()"の部分が、p_keyとp_valueとなっています。取得した2つの値はMyItemオブジェクトのインスタンスとして返ります。
public static readonly Parser<MyItem> parse2 = from lk in p_key
from lv in p_value
select new MyItem(lk, lv);
p_keyは下記の記述となっており、前後の空白を除去した1語を抽出するパーサーとなっています。
public static readonly Parser<string> p_key = Parse.Letter.AtLeastOnce().Text().Token();
p_valueは下記の記述となっており、「"」で囲まれた内部の値を抽出するパーサーとなっています。
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();
実行結果
プロジェクトを実行します。下図のウィンドウが表示されます。
上部のテキストボックスにパージングするテキストを入力します。今回は "Penguin "Jump"" を入力します。
[button2]をクリックします。下部のテキストボックスに "Penguin" と "Jump" がコロンで区切られて表示されました。Jumpを囲んでいた「"」も取り除かれて抽出できています。
同様に「Duck "8650"」でも動作確認します。
"Duck"と"8650"がコロンで区切られ表示されており、keyとvalueにパージングできていることが確認できました。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用