用c#中列表中的连续元素替换字符串占位符
Posted
技术标签:
【中文标题】用c#中列表中的连续元素替换字符串占位符【英文标题】:Replace a string placeholder with consecutive elements from a list in c# 【发布时间】:2021-12-05 09:58:47 【问题描述】:我知道有人问过类似的问题,但我找不到任何特别适合我需要的东西,而且我对正则表达式一无所知。
我有这样一个不同长度的句子:
在开发配方时提供 +$modifier% 的最高品质加成和 +$modifier% 的特殊特性几率。
所以 $modifier 是我所有这些的占位符。我有一个浮动列表,然后我将根据顺序替换它们。
在这种情况下,我有一个列表值 5,0.5。替换后的字符串应该以
结尾在开发配方时提供 +5% 的最高品质加成和 +0.5% 的特殊特性几率。
我想避免使用 string.Replace,因为文本可能会变得更长,而且我不想在它上面循环多次。任何人都可以提出一个好的方法吗?
干杯,谢谢 H
【问题讨论】:
除了实际的编码问题外,使用的概念似乎容易出错。如果用户希望值以不同的顺序出现在他们的文本中怎么办?对不同的值使用不同的占位符或使用占位符内的索引来处理值不是更明智吗? 嗨!我是这么想的,但这是我自己为我们的游戏制作的实际数据,所以我可以完全控制这些数据。它是基于 xml 的,它加载了一些结构以供软件验证并供游戏使用,无需用户外部输入。它可以帮助我拥有一个 $modifier 占位符,因为我每次创建新内容时都不必在源中手动重命名它们。 数据以特定名称加载并从同一个xml文件中检查,这一功能仅用于在描述中显示人类可读的文本。 【参考方案1】:Regex.Replace
方法有一个重载,您可以在其中指定一个回调方法来提供用于每次替换的值。
private string ReplaceWithList(string source, string placeHolder, IEnumerable<object> list)
// Escape placeholder so that it is a valid regular expression
placeHolder = Regex.Escape(placeHolder);
// Get enumerator for list
var enumerator = list.GetEnumerator();
// Use Regex engine to replace all occurences of placeholder
// with next entry from enumerator
string result = Regex.Replace(source, placeHolder, (m) =>
enumerator.MoveNext();
return enumerator.Current?.ToString();
);
return result;
这样使用:
string s = "Provides a +$modifier% bonus to Maximum Quality and a +$modifier% chance for Special Traits when developing a Recipe.";
List<object> list = new List<object> 5, 0.5 ;
s = ReplaceWithList(s, "$modifier", list);
请注意,您需要添加合理的错误处理。
【讨论】:
【参考方案2】:由于字符串在 CLR 中是不可变的,因此可能没有明智的方法来拆分字符串并以某种方式将其重新组合在一起。
一种是在您想要的标记字符串处拆分,插入您的替换值,然后再次连接您的部分:
var s = "Provides a +$modifier % bonus to Maximum Quality and a +$modifier % chance for Special Traits when developing a Recipe.";
var v = new List<float> 5.0f, 0.5f ;
var result = string.Concat(s.Split("$modifier").Select((s, i) => $"s(i < v.Count ? v[i] : string.Empty)"));
【讨论】:
以上是关于用c#中列表中的连续元素替换字符串占位符的主要内容,如果未能解决你的问题,请参考以下文章
java中有啥方法可以读取占位符的字符串,并且把占位符替换成参数
在没有数字占位符的 JavaScript 中复制 C# 的 string.format()