如何在C#中替换字符串中的多个子字符串?

时间:2019-07-20 10:52:05

标签: c#

我必须替换一个字符串中的多个子字符串(输入字符串的最大长度32)。我有一本大字典,其中有成千上万的项作为键值对。我需要检查每个词是否在字典中存在,如果在字典中存在,则用相应的值替换。输入的字符串可以有多个尾随空格。

此方法被称为数百万次,因此,它严重影响了性能。

代码中是否存在任何优化范围或其他更好的方法来实现此目的。

public static string RandomValueCompositeField(object objInput, Dictionary<string, string> g_rawValueRandomValueMapping) {

if (objInput == null)
    return null;

string input = objInput.ToString();
if (input == "")
    return input;

//List<string> ls = new List<string>();
int count = WhiteSpaceAtEnd(input);
foreach (string data in input.Substring(0, input.Length - count).Split(' ')) {

    try {
        string value;
        gs_dictRawValueRandomValueMapping.TryGetValue(data, out value);
        if (value != null) {

            //ls.Add(value.TrimEnd());
            input = input.Replace(data, value);
        }
        else {
            //ls.Add(data);
        }
    }
    catch(Exception ex) {

    }

}

//if (count > 0)
//    input = input + new string(' ', count);
    //ls.Add(new string(' ', count));

return input;
}

编辑:

我错过了问题中的一件重要事情。子字符串只能在输入字符串中出现一次。 Dictionay键和值的字符数相同。

1 个答案:

答案 0 :(得分:0)

这是一种方法,该方法将采用输入字符串,并通过查找“单词”(任何连续的非空白),然后检查该单词是否在字典中并将其替换为相应的值(如果找到)来构建新的字符串。这将解决Replace替换“子词”的问题(如果您拥有“ hello hell”,并且想要将“ hell”替换为“ heaven”,而又不希望它给您“天国天堂”)。它还解决了交换问题。例如,如果要在“是”中将“是”替换为“否”,将“否”替换为“是”,则不希望它先将其转换为“否”,然后再转换为“是”。

public string ReplaceWords(string input, Dictionary<string, string> replacements)
{
    var builder = new StringBuilder();
    int wordStart = -1;
    int wordLength = 0;
    for(int i = 0; i < input.Length; i++)
    {
        // If the current character is white space check if we have a word to replace
        if(char.IsWhiteSpace(input[i]))
        {
            // If wordStart is not -1 then we have hit the end of a word
            if(wordStart >= 0)
            {
                // get the word and look it up in the dictionary
                // if found use the replacement, if not keep the word.
                var word = input.Substring(wordStart, wordLength);
                if(replacements.TryGetValue(word, out var replace))
                {
                    builder.Append(replace);
                }
                else
                {
                    builder.Append(word);
                }
            }

            // Make sure to reset the start and length
            wordStart = -1;
            wordLength = 0;

            // append whatever whitespace was found.
            builder.Append(input[i]);
        }
        // If this isn't whitespace we set wordStart if it isn't already set
        // and just increment the length.
        else
        {
            if(wordStart == -1) wordStart = i;
            wordLength++;
        }
    }

    // If wordStart is not -1 then we have a trailing word we need to check.
    if(wordStart >= 0)
    {
        var word = input.Substring(wordStart, wordLength);
        if(replacements.TryGetValue(word, out var replace))
        {
            builder.Append(replace);
        }
        else
        {
            builder.Append(word);
        }
    }

    return builder.ToString();
}