繁体   English   中英

字符串替换为字典值

[英]String Replace with Dictionary Values

我用字典中的值替换字符串中的单词时遇到一些问题。 这是我当前代码的一小部分示例:

Dictionary<string, string> replacements = new Dictionary<string, string>()
{
    {"ACFT", "AIRCRAFT"},
    {"FT", "FEET"},
};
foreach(string s in replacements.Keys)
{
    inputBox.Text = inputBox.Text.Replace(s, replacements[s]);
}

执行代码时,如果文本框中有ACFT ,则将它替换为AIRCRAFEET因为它在字符串中看到FT部分。 我需要以某种方式对此加以区分,仅替换整个单词。

因此,例如,如果我的包装盒中有ACFT ,则应将其替换为AIRCRAFT 而且,如果我的包装盒中有FT ,请用FEET代替它。

所以我的问题是, 在替换单词时,如何才能匹配整个单词?

编辑:我希望能够使用和替换多个单词。

在替换单词时,我怎么才能匹配整个单词?

使用正则表达式(如David Pilkington所建议)

Dictionary<string, string> replacements = new Dictionary<string, string>()
{
    {"ACFT", "AIRCRAFT"},
    {"FT", "FEET"},
};

foreach(string s in replacements.Keys)
{
    var pattern = "\b" + s + "\b"; // match on word boundaries
    inputBox.Text = Regex.Replace(inputBox.Text, pattern, replacements[s]);
}

但是,如果您可以控制设计,那么我宁愿使用诸如"{ACFT}""{FT}" (它们具有明确的边界),因此您可以将它们与String.Replace一起使用。

使用if条件。

foreach(string s in replacements.Keys) {
    if(inputBox.Text==s){
        inputBox.Text = inputBox.Text.Replace(s, replacements[s]);
    }
}

修改问题后更新

 string str = "ACFT FTT";
 Dictionary<string, string> replacements = new Dictionary<string, string>()
 {
     {"ACFT", "AIRCRAFT"},
     {"FT", "FEET"},
 };
 string[] temp = str.Split(' ');
 string newStr = "";
 for (int i = 0; i < temp.Length; i++)
 {

     try
     {
         temp[i] = temp[i].Replace(temp[i], replacements[temp[i]]);
     }
     catch (KeyNotFoundException e)
     {
         // not found..
     }
     newStr+=temp[i]+" ";
 }
 Console.WriteLine(  newStr);

问题是您要替换整个字符串中子字符串的每个实例。 如果要替换的是仅完整的,用空格分隔的“ ACFT”或“ FT”实例,则需要使用String.Split()创建一组令牌。

例如:

string tempString = textBox1.Text;
StringBuilder finalString = new StringBuilder();
foreach (string word in tempString.Split(new char[] { ' ' })
{
    foreach(string s in replacements.Keys)
    {
        finalString.Append(word.Replace(s, replacements[s]));
    }
}

textBox1.Text = finalString.ToString();

我在这里使用StringBuilder是因为串联需要每次都创建一个新字符串,而且长期来看效率极低。 如果您希望进行少量串联,则可以避免使用字符串。

请注意,您的设计中存在一些细微的变化-如果您的KeyValuePair的值与随后在字典迭代中出现的键相同,则替换将被覆盖。

我认为您可能要替换inputText中的最大长度subStr。

        int maxLength = 0;
        string reStr = "";
        foreach (string s in replacements.Keys)
        {
            if (textBox2.Text.Contains(s))
            {
                if (maxLength < s.Length)
                {
                    maxLength = s.Length;
                    reStr = s;
                }
            }
        }
        if (reStr != "")
            textBox2.Text = textBox2.Text.Replace(reStr, replacements[reStr]);

这是非常时髦的方式。

首先,您需要使用正则表达式( Regex ),因为它具有良好的内置功能以匹配单词边界。

因此,代码的关键行是定义Regex实例:

var regex = new Regex(String.Format(@"\b{0}\b", Regex.Escape("ACFT"));

\\b标记查找单词边界。 Regex.Escape确保如果您的其他任何键都有特殊的Regex字符,则可以将它们转义出去。

然后,您可以像这样替换文本:

var replacedtext = regex.Replace("A FT AFT", "FEET");

您将获得replacedtext == "A FEET AFT"

现在,这是时髦的部分。 如果从当前词典开始,则可以定义一个函数,该函数可以一次性完成所有替换操作。

这样做:

Func<string, string> funcreplaceall =
    replacements
        .ToDictionary(
            kvp => new Regex(String.Format(@"\b{0}\b", Regex.Escape(kvp.Key))),
            kvp => kvp.Value)
        .Select(kvp =>
            (Func<string, string>)(x => kvp.Key.Replace(x, kvp.Value)))
        .Aggregate((f0, f1) => x => f1(f0(x)));

现在,您可以这样称呼它:

inputBox.Text = funcreplaceall(inputBox.Text);

无需循环!

就像一个健全性检查,我得到了这个:

funcreplaceall("A ACFT FT RACFT B") == "A AIRCRAFT FEET RACFT B"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM