我有一个带有特殊字符的字符串,我必须用一个索引(左填充n '0‘)替换这些字符。
快速示例以获得更好的解释:
我有字符串“098000998383 $$$$”,索引(整数)3的结果应该是“098000998383 0003”。
这些特殊字符不一定是按顺序排列的。源字符串可能为空,也可能不包含任何特殊字符。
我已经写了一些有用的函数。
public static class StringExtensions
{
public static string ReplaceCounter(this string source, int counter, string character)
{
string res = source;
try
{
if (!string.IsNullOrEmpty(character))
{
if (res.Contains(character))
{
// Get ALL Indexes position of character
var Indexes = GetIndexes(res, character);
int max = GetMaxValue(Indexes.Count);
while (counter >= max)
{
counter -= max;
}
var new_value = counter.ToString().PadLeft(Indexes.Count, '0');
for (int i = 0; i < Indexes.Count; i++)
{
res = res.Remove(Indexes[i], 1).Insert(Indexes[i], new_value[i].ToString());
}
}
}
}
catch (Exception)
{
res = source;
}
return res;
}
private static List<int> GetIndexes(string mainString, string toFind)
{
var Indexes = new List<int>();
for (int i = mainString.IndexOf(toFind); i > -1; i = mainString.IndexOf(toFind, i + 1))
{
// for loop end when i=-1 (line.counter not found)
Indexes.Add(i);
}
return Indexes;
}
private static int GetMaxValue(int numIndexes)
{
int max = 0;
for (int i = 0; i < numIndexes; i++)
{
if (i == 0)
max = 9;
else
max = max * 10 + 9;
}
return max;
}
}但我真的不喜欢它(首先,因为我把字符作为字符串传递..。而不是作为焦炭)。
string source = "000081059671####=1811";
int index = 5;
string character = "#";
string result = source.ReplaceCounter(index, character);它能更加优化和紧凑吗?一些善良的灵魂能帮我吗?
提前感谢
编辑
索引是可变的,因此:
如果索引为15
string source = "000081059671####=1811";
int index = 15;
string character = "#";
string result = source.ReplaceCounter(index, character);
// result = "0000810596710015=1811"这应该是检查我上面发布的代码中的索引> max号,如果发生这种情况,我会从索引中删除" max“值,直到索引
穆克斯号是什么?如果特殊字符数为4(如下面的示例所示),则最大值为9999。
string source = "000081059671####=1811";
// max number 9999发布于 2021-07-30 10:14:37
又一次编辑
从评论来看,似乎可以使用一个以上的数字。在这种情况下,可以将counter转换为string,并将其作为char[]来选择要在每次迭代中使用的字符:
public static string ReplaceCounter(this string source,
int counter,
char character)
{
var sb=new StringBuilder(source);
var replacements=counter.ToString();
int r=replacements.Length-1;
for(int i=sb.Length-1;i>=0;i--)
{
if(sb[i]==character)
{
sb[i]=r>=0 ? replacements[r--] : '0';
}
}
return sb.ToString();
}这可以用于任意数量的数字。"0980 0099 8383 $$$$".ReplaceCounter(15,'$')生成0980 0099 8383 0015
编辑
在发布了最初的答案后,我记得有一个可以通过使用StringBuilder来修改字符串而不需要分配。在这种情况下,需要用一个字符替换最后一个匹配,用另一个字符替换所有其他匹配。这可以是一个简单的反向迭代:
public static string ReplaceCounter(this string source,
int counter,
char character)
{
var sb=new StringBuilder(source);
bool useChar=true;
for(int i=sb.Length-1;i>=0;i--)
{
if(sb[i]==character)
{
sb[i]=useChar?(char)('0'+counter):'0';
useChar=false;
}
}
return sb.ToString();
}
Console.WriteLine("0000##81#059671####=1811".ReplaceCounter(5,'#'));
Console.WriteLine("0980 0099 8383 $$$$".ReplaceCounter(3,'$'));
------
0000008100596710005=1811
0980 0099 8383 0003原始答案
任何字符串修改操作都会产生一个需要垃圾收集的新的临时字符串。这样加起来太快了,所以在处理大量文本或请求时,避免临时字符串会导致速度提高超过10倍。这比使用并行处理要好。
可以使用Regex.Replace执行复杂的替换,而无需分配临时字符串。您可以使用替换重载之一,使用MatchEvaluator生成动态输出,而不仅仅是单个值。
在这种情况下:
var source = "0000##81#059671####=1811";
var result = Regex.Replace(source,"#", m=>m.NextMatch().Success?"0":"5");
Console.WriteLine(result);
--------
0000008100596710005=1811Match.NextMatch()返回源中的下一个匹配,因此可以使用m.NextMatch().Success来标识最后一个匹配,并将其替换为index。
如果该字符是Regex模式字符之一,则此操作将失败。这可以通过使用Regex.Escape(字符串)转义字符来避免。
这可以用扩展方法打包。
public static string ReplaceCounter(this string source,
int counter,
string character)
{
return Regex.Replace(source,
Regex.Escape(character),
m=>m.NextMatch().Success?"0":counter.ToString());
}
public static string ReplaceCounter(this string source,
int counter,
char character)
=>ReplaceCounter(source,counter,character.ToString());这段代码
var source= "0980 0099 8383 $$$$";
var result=source.ReplaceCounter(5,"$");返回
0980 0099 8383 0003发布于 2021-07-30 08:52:52
我建议这样的解决办法(摆脱帮助者的方法:
public static class StringExtensions
{
public static string ReplaceCounter(this string source, int counter, char character)
{
string res = source;
string strCounter = counter.ToString();
bool counterTooLong = false;
int idx;
// Going from the and backwards, we fill with counter digits.
for(int i = strCounter.Length - 1; i >= 0; i--)
{
idx = res.LastIndexOf(character);
// if we run out of special characters, break the loop.
if (idx == -1)
{
counterTooLong = true;
break;
}
res = res.Remove(idx, 1).Insert(idx, strCounter[i].ToString());
}
// If we could not fit the counter, we simply throw exception
if (counterTooLong) throw new InvalidOperationException();
// If we did not fill all placeholders, we fill it with zeros.
while (-1 != (idx = res.IndexOf(character))) res = res.Remove(idx, 1).Insert(idx, "0");
return res;
}
}https://stackoverflow.com/questions/68587684
复制相似问题