C#列出输入字符串的替换值 - 最快的方式

时间:2017-08-15 21:24:41

标签: c# regex replace lambda lookup

我有一个MyObj的静态列表,它是从json文件动态填充的。

public class MyObj
{
    public string OriginalValue { get; set; } = "";
    public string ReplacementValue { get; set; } = "";
}

为了这个问题,我将使用foo值填充列表。

public static List<MyObj> ReplacementValues = new MyObj[]
{
    new MyObj() { OriginalValue = "{a}",  ReplacementValue = "Queen" },
    new MyObj() { OriginalValue = "{m}",  ReplacementValue = "Cersei" },
    new MyObj() { OriginalValue = "{s1}", ReplacementValue = "Khaleesi" },
    new MyObj() { OriginalValue = "{p}",  ReplacementValue = "Harry" },
    ...
    new MyObj() { OriginalValue = "{_2_29sa}",  ReplacementValue = "229Z" }
}.ToList();

然后我有一个输入字符串(可能是任何真正的,相同{x}值的倍数,30倍):

var inputstring = "The Khal is looking for a {a}, her name must not be {m}. He found one called {s1}. {p} Potter {p}{p}{p}{p}{p}{p}";

以何种方式可以快速迭代值,用替换值替换字符串中的值。

我可以使用foreach等进行indexOf循环并遍历静态列表,但列表可能会变得非常大,可以说15000个条目很大。我知道它听起来并不多,但替换应该接近实时&#39; ish,如果输入字符串中有400x相同的值,可能会在15k列表中循环这么多次

是否有更快的lambda或Regex方法快速将字符串中的值替换为查找列表中的值?

3 个答案:

答案 0 :(得分:2)

我建议使用let router = new Router({ mode: 'history', routes: [ { path: '/profile', name: 'Profile', component: Profile, meta: { auth: true // A protected route }, }, { path: '/login', name: 'Login', component: Login, // Unprotected route }, ] }) /* Use this hook on all the routes that need to be protected instead of beforeRouteEnter on each one explicitly */ router.beforeEach((to, from, next) => { if (to.meta.auth && userNotLoggedIn) { next('/login') } else { next() } }) // Your Vue instance new Vue({ el: '#app', router, // ... }) 代表Regex.Replace是最佳选择:

MatchEvaluator

如果你有C#7.0,你可以改用它:

var dictReplacement = ReplacementValues.ToDictionary(rv => rv.OriginalValue, rv => rv.ReplacementValue);

var ans = Regex.Replace(inputstring, @"\{.+?\}", m => dictReplacement.ContainsKey(m.Value) ? dictReplacement[m.Value] : m.Value);

答案 1 :(得分:1)

鉴于您的列表可能包含许多不同的对象,我认为最好扫描更短的输入字符串,然后只替换您在那里找到的标记。

您可以将其与字典的快速检索时间结合起来

Dictionary<string, string> test = new Dictionary<string, string>()
{
    {"{a}", "the new hero"},
    {"{b}", "of the new era"}
};
.....

string input = GetInputString();
int posStart = 0;
while ((posStart = input.IndexOf("{", posStart)) != -1)
{
    int posEnd = replacements.IndexOf("}", posStart+1);
    if(posEnd == -1)
        break;

    string sub = input.Substring(posStart, posEnd+1-posStart);
    if(test.ContainsKey(sub))
        input = input.Replace(sub, test[sub]);
    posStart++;
}
Console.WriteLine(input);

答案 2 :(得分:0)

我认为最简单的方法是使用foreach进行String.Replace循环。

foreach(var r in ReplacementValues)
{
      inputString.Replace(r.OriginalValue, r.ReplacementValue);
}

或者你可以简化这一点(注意效率较低):

ReplacementValues.ForEach(r => inputList.Replace(r.OriginalValue, r.ReplacementValue);