3

ユーザーが選択する文字列テンプレートがあります。そのテンプレートを取得して、要求された情報を入力する必要があります。

string templateString = "%author% - %title% (%year%)";

.Contains() と .Replace() を実行できますが、テンプレートには次のような大量の入力または少量の入力が含まれる可能性があります。

string templateString = "%author% - %publisher% - %isbn% - %asin% - %title% (%year%)";

したがって、ユーザーが選択できるすべてのオプションに対して .Contains() および .Replace() を実行するのは非効率的です。どんな助けでも大歓迎です。これは、何千ものアイテムで使用されます。

プログラム自体は、ユーザーが入力するファイルの数に関係なく (電子ブック、私たちの中には何千ものファイルを持っている人もいます)、個々のユーザーのテンプレートに基づいてすべての電子ブックの名前を変更し、電子ブックからスクレイピングしたメタデータで情報を埋めます。

4

2 に答える 2

4

これを別の場所に投稿しましたが、あなたの場合は良いアプローチのようです(私もこれを自分でやったことがあります)。基本的に、一致評価コールバックで正規表現置換を使用します。

regex = new Regex(@"\%(?<value>.*?)\%", 
    RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);

string replacedText = regex.Replace(<text>, 
    new MatchEvaluator(this.EvaluateMatchCallback));

次に、コールバックは次のようになります。

private string EvaluateMatchCallback(Match match) {
    string templateInsert = match.Groups["value"].Value;
    // or whatever
    string replacedText = GetReplacementTextBasedOnTemplateValue(templateInsert);
    return replacedText;
}

WhereGetReplacementTextBasedOnTemplateValueは、正規表現によって一致したプレースホルダーに対応する値を返すメソッドです。

于 2012-08-16T20:44:20.407 に答える
1

私は過去にこれをやったことがあります。を使用する代わりに、使用可能なすべてのオプションを.Contains呼び出すだけです。.Replace(pattern, replacement)典型的なユーザー指向 (データの表示/入力など) のアプリでは、ユーザーは速度の低下に気付くことはありません。

パフォーマンスの最適化を試みる前に、パフォーマンスの問題があることを確認する必要があります。時間を無駄にしている可能性が高いです。

テスト データ: 以下のテスト コードを使用すると、25,000 冊の「本」の 10 個の値を置き換えるのに 2 秒もかからないことがわかります。そのほとんどは、コンソールへの書き込みが原因です (Console.WriteLine() を削除すると、ランタイムは 160 ミリ秒未満に低下します)。書籍を a List<String>()) に追加するだけです。私にはかなり受け入れられるようです。

String template = @"%index%.  %title% - %author% [%isbn%] - %year%";
            Dictionary<String, String> values = new Dictionary<String, String> { { "title", "A day in the life of..." }, { "author", "Joe S. Schmoe" }, { "year", "1945" }, { "isbn", "987-987-987-987-987" }, { "one", "1" }, { "two", "2" }, { "three", "3" }, { "four", "4" }, { "five", "5" }, { "six", "6" }, { "seven", "7" } };
            String output = string.Empty;
            Stopwatch watch = new Stopwatch();

            watch.Start();
            for (Int32 index = 0; index < 25000; index++) {
                output = template;
                foreach (String key in values.Keys) {
                    output = output.Replace("%" + key + "%", values[key]);
                }
                output = output.Replace("%index%", index.ToString());
                Console.WriteLine(output);
            }
            watch.Stop();

            Console.WriteLine("Elapsed time (ms): " + watch.ElapsedMilliseconds.ToString());
于 2012-08-16T20:40:35.537 に答える