2

ユーザーが入力できるいくつかの機能を提供するプログラムを作成しています。function と function を使用して文字列を大文字に変換する関数がある$upper(string)とします$lower(string)。ユーザーは、プレースホルダーを使用してコンテンツを挿入しながらテキスト ボックスにそれらを入力できます (たとえば、曲のタイトルの場合は %T)。プレースホルダーと関数の両方を使用して、ユーザーは完全な命名パターンを入力できます。

関数は入れ子にすることができ、最も内側の関数を最初に実行したいと考えています。今、それを識別するための正規表現を探しています。英語で、私は探していますa function (and its value) that does not contain another function.

テスト中、ブラケットの代わりにハイフンを使用し、$ 記号は使用しません。これは非常に読みやすいです。したがって、テスト中の機能はlower-sometext-.

これまでの私の推測は次のとおりです。

(lower|upper)-(?!((lower|upper)-.*-))-

私は次のように読みました。

  • upperまたはlower、という単語を見つけます。
  • その後にハイフン、
  • upper単語またはlower、ハイフン、ランダムな数のランダムな文字、およびハイフンではないものが続きます
  • ハイフンが続きます。

しかし、それは受け入れませんlower-sometext-。2時間以上いろいろ試しているのですが、わかりません...

4

1 に答える 1

1

別のアプローチを使用します。最初に最も内側の関数を探す代わりに、最も外側の関数から始めて、その値を再帰的に解決します。

したがって、ストリングについては、upper(lower(sometext))最初にアッパーを「処理」します。ただし、実際に ToUpper() を適用する前に、その値に対して同じ関数を呼び出します。この場合はlower(sometext). 次に、同じことをもう一度実行します。値の実行関数の結果に ToLower() を適用します - この場合のみsometext. 関数が含まれていないため、execute メソッドは戻りsometext、再帰を終了します。

C#で関数を作成しました

public string execute(string text)
{
    string pattern = @"(lower|upper)\((.*)\)";
    Match m = Regex.Match(text, pattern);
    if (m.Success)
    {
        switch (m.Groups[1].Value)
        {
            case "lower":
                return execute(m.Groups[2].Value).ToLower();
            case "upper":
                return execute(m.Groups[2].Value).ToUpper();
            default:
                return null;
        }
    }
    else
        return text;
}

そして、文字列で関数を呼び出すことができます:

string result = "upper(lower(sometext))";

繰り返しますが、重要な部分はスイッチ内にあります。呼び出す前、ToLower()またはToUpper()値の実行メソッドを呼び出す前に。この関数の結果は常にリテラルであり、関数を含むことはありません。また、それは本当にうまくスケーリングします。

于 2013-05-20T03:09:49.903 に答える