我有我需要做一些替换的字符串。 我有一个Dictionary<string, string>
其中I具有搜索替换定义对。 我创建了以下扩展方法来执行此操作:
public static string Replace(this string str, Dictionary<string, string> dict)
{
StringBuilder sb = new StringBuilder(str);
return sb.Replace(dict).ToString();
}
public static StringBuild Replace(this StringBuilder sb,
Dictionary<string, string> dict)
{
foreach (KeyValuePair<string, string> replacement in dict)
{
sb.Replace(replacement.Key, replacement.Value);
}
return sb;
}
是否有这样做的更好的办法?
Answer 1:
如果数据标记化(即“亲爱的$ $名称,如$日期$的您的余额是$ $金额”),那么Regex
可能是有用的:
static readonly Regex re = new Regex(@"\$(\w+)\$", RegexOptions.Compiled);
static void Main() {
string input = @"Dear $name$, as of $date$ your balance is $amount$";
var args = new Dictionary<string, string>(
StringComparer.OrdinalIgnoreCase) {
{"name", "Mr Smith"},
{"date", "05 Aug 2009"},
{"amount", "GBP200"}
};
string output = re.Replace(input, match => args[match.Groups[1].Value]);
}
然而,如果没有这样的事情,我希望你Replace
循环大概是尽可能你可以做,不用去极端的长度。 如果不记号化,也许简介它; 是Replace
实际上是一个问题吗?
Answer 2:
使用LINQ这样做:
var newstr = dict.Aggregate(str, (current, value) =>
current.Replace(value.Key, value.Value));
字典是你的搜索替换定义字典对象对。
str是你的字符串,你需要做一些与替代。
Answer 3:
似乎是合理的我,除了一两件事:这是为了敏感。 例如,以“$ X $ Y”和替换词典的输入字符串:
"$x" => "$y"
"$y" => "foo"
替换的结果要么是 “富foo”的或取决于哪个替换首先执行“$ y的foo”的。
你可以控制使用排序List<KeyValuePair<string, string>>
代替。 另一种方法是通过串走确保你不消耗替代在进一步替换操作。 这可能是很多困难,但。
Answer 4:
下面是@马克的伟大答案轻度重因素的版本,使作为一个扩展可用的方法正则表达式的功能:
static void Main()
{
string input = @"Dear $name$, as of $date$ your balance is $amount$";
var args = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
args.Add("name", "Mr Smith");
args.Add("date", "05 Aug 2009");
args.Add("amount", "GBP200");
Regex re = new Regex(@"\$(\w+)\$", RegexOptions.Compiled);
string output = re.replaceTokens(input, args);
// spot the LinqPad user // output.Dump();
}
public static class ReplaceTokensUsingDictionary
{
public static string replaceTokens(this Regex re, string input, IDictionary<string, string> args)
{
return re.Replace(input, match => args[match.Groups[1].Value]);
}
}
Answer 5:
用马克Gravell的正则表达式的解决方案,首先检查时,如果一个令牌可用即使用的containsKey,这对防止KeyNotFoundException错误:
string output = re.Replace(zpl, match => { return args.ContainsKey(match.Groups[1].Value) ? arg[match.Groups[1].Value] : match.Value; });
使用以下略作修改的示例代码时(第一参数具有不同的名称):
var args = new Dictionary<string, string>(
StringComparer.OrdinalIgnoreCase)
{
{"nameWRONG", "Mr Smith"},
{"date", "05 Aug 2009"},
{"AMOUNT", "GBP200"}
};
这将产生以下:
“亲爱的$ $名,截至2009年08月05日的余额为GBP200”
Answer 6:
这个给你:
public static class StringExm
{
public static String ReplaceAll(this String str, KeyValuePair<String, String>[] map)
{
if (String.IsNullOrEmpty(str))
return str;
StringBuilder result = new StringBuilder(str.Length);
StringBuilder word = new StringBuilder(str.Length);
Int32[] indices = new Int32[map.Length];
for (Int32 characterIndex = 0; characterIndex < str.Length; characterIndex++)
{
Char c = str[characterIndex];
word.Append(c);
for (var i = 0; i < map.Length; i++)
{
String old = map[i].Key;
if (word.Length - 1 != indices[i])
continue;
if (old.Length == word.Length && old[word.Length - 1] == c)
{
indices[i] = -old.Length;
continue;
}
if (old.Length > word.Length && old[word.Length - 1] == c)
{
indices[i]++;
continue;
}
indices[i] = 0;
}
Int32 length = 0, index = -1;
Boolean exists = false;
for (int i = 0; i < indices.Length; i++)
{
if (indices[i] > 0)
{
exists = true;
break;
}
if (-indices[i] > length)
{
length = -indices[i];
index = i;
}
}
if (exists)
continue;
if (index >= 0)
{
String value = map[index].Value;
word.Remove(0, length);
result.Append(value);
if (word.Length > 0)
{
characterIndex -= word.Length;
word.Length = 0;
}
}
result.Append(word);
word.Length = 0;
for (int i = 0; i < indices.Length; i++)
indices[i] = 0;
}
if (word.Length > 0)
result.Append(word);
return result.ToString();
}
}
文章来源: C# String replace with dictionary