初心者のためのC#プログラミング本格入門53 - 外見から考えよう
「 ( 1 + 2 ) / 3 」の様な複数の式を解析するには、新しいオブジェクトを創らねばなりません。ですが、初心者の方はまだ不慣れだと思いますので、新しいオブジェクトを作る過程を丁寧に説明します。
単一の式ならば解析できますので、先ずは複数の式を区切る方法について考えましょう。式を区切る方法は、前回()記号を使用する事を決定しましたので、「(」記号から「)」記号までの文字列を切出せれば実現できます。早速その方法をプログラムで実現する事を考えましょう。
初心者がいきなり答えを出そうとしても混乱するので、使用する側のプログラムを作るのがベストです。
static void Main()
{
//結果をチェック
System.Tuple<bool, string, string> result =
CutExpression( " ( + 1 2 3 ) / 3" );
System.Console.WriteLine( "元となる式:" + result.Item2 );
System.Console.WriteLine( "式は正しい?:" + result.Item1 );
System.Console.WriteLine( "取り出した式:" + result.Item3 );
//エラーの場合もチェック
System.Console.WriteLine( "" );
System.Tuple<bool, string, string> error =
CutExpression( " + 1 2 3 / 3" );
System.Console.WriteLine( "元となる式:" + error.Item2 );
System.Console.WriteLine( "式は正しい?:" + error.Item1 );
System.Console.WriteLine( "取り出した式:" + error.Item3 );
}
static System.Tuple<bool, string, string> CutExpression(
string expression )
{
System.Tuple<bool, string, string> error =
new System.Tuple<bool, string, string>(
false, expression, "" );
return error;
}
最低限必要な要素、「式の正しさ」、「元の式」、「取り出した式」を取得する事を考えます。なお、呼び出される側のCutExpression静的メソッドは、ひとまずエラーを表すインスタンスを返すようにしておきます。このプログラムを元にして、徐々にプログラムを完成させます。これで完成イメージが湧いたと思います。次はCutExpression静的メソッドの内容を考えましょう。文字列を部分的に取得するメソッドを解説した事がありますが覚えていますか?正解は「Substring」メソッドです。Substringは、開始位置と文字の個数を指定して呼び出します。ということは、開始位置と文字の個数を記憶する変数が必要です。
static System.Tuple<bool, string, string> CutExpression(
string expression )
{
int startIndex = -1;
int count = -1;
System.Tuple<bool, string, string> error =
new System.Tuple<bool, string, string>(
false, expression, "" );
return error;
}
目的が分かったら後は簡単です。順番に考えていくだけです。開始位置を判定するプログラムを考えてみましょう。
for ( int i = 0; i < expression.Length; i++ )
{
char tmp = expression[ i ];
if ( tmp == '(' )
{
startIndex = i + 1;
}
}
「(」記号そのものは必要ないので次の位置を記録しています。その点さえ注意すれば簡単です。次は取り出す文字の個数を計算するために、終了位置も一緒に割り出しましょう。
for ( int i = 0; i < expression.Length; i++ )
{
char tmp = expression[ i ];
if ( tmp == '(' )
{
startIndex = i + 1;
continue;
}
if ( tmp == ')' )
{
endIndex = i;
break;
}
}
int count = endIndex - startIndex;
このプログラムは理解できると思います。後は、エラー処理とSubstringメソッドを呼び出しを付け加えると完成です。
static System.Tuple<bool, string, string> CutExpression(
string expression )
{
//()記号の範囲を決定
int startIndex = -1;
int endIndex = -1;
for ( int i = 0; i < expression.Length; i++ )
{
char tmp = expression[ i ];
if ( tmp == '(' )
{
startIndex = i + 1;
continue;
}
if ( tmp == ')' )
{
endIndex = i;
break;
}
}
//エラー判定
if ( startIndex == -1 | endIndex == -1 )
{
System.Tuple<bool, string, string> error =
new System.Tuple<bool, string, string>(
false, expression, "" );
return error;
}
//()内の式を取り出す
int count = endIndex - startIndex;
string cutExpression = expression.Substring(
startIndex, count );
System.Tuple<bool, string, string> result =
new System.Tuple<bool, string, string>(
true, expression, cutExpression );
return result;
}
エラー判定の「if ( startIndex == -1 | endIndex == -1 )」というプログラムは、OR論理演算子「|」(Shiftキーを押しながら円記号(¥)のキーを押せば入力できます)を使用しています。プログラムの意味は、「startIndex変数が-1もしくは、endIndex変数が-1ならば{}内のプログラムを実行する」です。AND論理演算子(&)と違い、どちらかの条件が満たされれば{}内のプログラムが実行されます。
以上で括弧内の式を取り出す事が可能となりました。これは複数の式を解析するための重要な一歩です。