![](/img/trans.png)
[英]String Replace()/regex replace - Replacing strings in array of strings?
[英]Replacing strings in a string array efficiently
我有一个完整的字符串数组。 我正在尝试将某些Guid替换为其他Guid。 我的方法如下:
var newArray = this.to.Select(s => s.Replace("e77f75b7-2373-dc11-8f13-0019bb2ca0a0", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
.Replace("fbd0c892-2373-dc11-8f13-0019bb2ca0a0", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
.Replace("76cd4297-1e31-dc11-95d8-0019bb2ca0a0", "eb892fb0-fe17-e811-80d8-00155d5ce473")
.Replace("cd42bb68-2073-dc11-8f13-0019bb2ca0a0", "dc6077e2-fe17-e811-80d8-00155d5ce473")
.Replace("96b97150-cd45-e111-a3d5-00155d10010f", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
).ToArray();
我有几个字段正在执行此操作,并且它导致OutOfMemoryException。 是否因为Replace()方法每次都创建一个新数组? 是否有更有效的方法来处理字符串数组? 该方法正在运行成千上万的记录,因此我认为这是问题所在。 当我注释掉这些行时,我不会例外。
编辑:在每种情况下,“ to”变量中的数据都是短字符串,但这将为数千条记录运行。 因此,“ to”可能看起来像这样一个记录。
"systemuser|76cd4297-1e31-dc11-95d8-0019bb2ca0a0;contact|96b97150-cd45-e111-a3d5-00155d10010f"
它可能包含我要替换的任何GUID,因此即使该记录可能只有一个GUID,我也需要运行全套replaces(),以防万一其中包含其中的任何一个。
任何指针都很棒! 谢谢。
我会使用替换字典-它更易于维护和理解(我认为),因此它一直很容易:
样板并创建演示数据/替换字典:
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
internal class Program
{
static void Main(string[] args)
{
// c#7 inline func
string[] CreateDemoData(Dictionary<string, string> replDict)
{
// c#7 inline func
string FilText(string s) => $"Some text| that also incudes; {s} and more.";
return Enumerable
.Range(1, 5)
.Select(i => FilText(Guid.NewGuid().ToString()))
.Concat(replDict.Keys.Select(k => FilText(k)))
.OrderBy(t => Guid.NewGuid().GetHashCode())
.ToArray();
}
// replacement dict
var d = new Dictionary<string, string>
{
["e77f75b7-2373-dc11-8f13-0019bb2ca0a0"] = "e77f75b7-replaced",
["fbd0c892-2373-dc11-8f13-0019bb2ca0a0"] = "fbd0c892-replaced",
["76cd4297-1e31-dc11-95d8-0019bb2ca0a0"] = "76cd4297-replaced",
["cd42bb68-2073-dc11-8f13-0019bb2ca0a0"] = "cd42bb68-replaced",
["96b97150-cd45-e111-a3d5-00155d10010f"] = "96b97150-replaced",
};
var arr = CreateDemoData(d);
创建实际替换数组的代码:
// c#7 inline func
string Replace(string a, Dictionary<string, string> dic)
{
foreach (var key in dic.Keys.Where(k => a.Contains(k)))
a = a.Replace(key, dic[key]);
return a;
}
// select value from dict in key in dict else leave unmodified
var b = arr.Select(a => Replace(a, d));
// if you have really that much data (20k guids of ~50byte length
// is not really much imho) you can use the same approach for in
// place replacement - just foreach over your array.
输出代码:
Console.WriteLine("\nBefore:");
foreach (var s in arr)
Console.WriteLine(s);
Console.WriteLine("\nAfter:");
foreach (var s in b)
Console.WriteLine(s);
Console.ReadLine();
}
}
输出:
Before:
Some text| that also incudes; a5ceefd8-1388-47cd-b69e-55b6ddbbc133 and more.
Some text| that also incudes; 76cd4297-1e31-dc11-95d8-0019bb2ca0a0 and more.
Some text| that also incudes; 3311a8c5-015e-4260-af80-86b20b277234 and more.
Some text| that also incudes; ed10c79c-dad6-4c88-865c-4d7624945d66 and more.
Some text| that also incudes; 96b97150-cd45-e111-a3d5-00155d10010f and more.
Some text| that also incudes; 0226d9b1-c5f0-41fb-9294-bc9297e8afd9 and more.
Some text| that also incudes; e77f75b7-2373-dc11-8f13-0019bb2ca0a0 and more.
Some text| that also incudes; a04d1e34-e7bc-4bbc-ae0e-12ec846a353c and more.
Some text| that also incudes; cd42bb68-2073-dc11-8f13-0019bb2ca0a0 and more.
Some text| that also incudes; fbd0c892-2373-dc11-8f13-0019bb2ca0a0 and more.
输出:
After:
Some text| that also incudes; a5ceefd8-1388-47cd-b69e-55b6ddbbc133 and more.
Some text| that also incudes; 76cd4297-replaced and more.
Some text| that also incudes; 3311a8c5-015e-4260-af80-86b20b277234 and more.
Some text| that also incudes; ed10c79c-dad6-4c88-865c-4d7624945d66 and more.
Some text| that also incudes; 96b97150-replaced and more.
Some text| that also incudes; 0226d9b1-c5f0-41fb-9294-bc9297e8afd9 and more.
Some text| that also incudes; e77f75b7-replaced and more.
Some text| that also incudes; a04d1e34-e7bc-4bbc-ae0e-12ec846a353c and more.
Some text| that also incudes; cd42bb68-replaced and more.
Some text| that also incudes; fbd0c892-replaced and more.
我将使用正则表达式提取字段,然后使用替换字典来应用更改,然后重新构造字符串,从而完成一次扫描:
IDictionary<string, string> replacements = new Dictionary<string, string>
{
{"76cd4297-1e31-dc11-95d8-0019bb2ca0a0","something else"},
//etc
};
var newData = data
//.AsParallel() //for speed
.Select(d => Regex.Match(d, @"^(?<f1>[^\|]*)\|(?<f2>[^;]*);(?<f3>[^\|]*)\|(?<f4>.*)$"))
.Where(m => m.Success)
.Select(m => new
{
field1 = m.Groups["f1"].Value,
field2 = m.Groups["f2"].Value,
field3 = m.Groups["f3"].Value,
field4 = m.Groups["f4"].Value
})
.Select(x => new
{
x.field1,
field2 = replacements.TryGetValue(x.field2, out string r2) ? r2 : x.field2,
x.field3,
field4 = replacements.TryGetValue(x.field4, out string r4) ? r4 : x.field4
})
.Select(x => $"{x.field1}|{x.field2};{x.field3}|{x.field4}")
.ToArray();
您是否已使用StringBuilder测试过?
StringBuilder sb = new StringBuilder(string.Join(",", this.to));
string tempStr = sb
.Replace("e77f75b7-2373-dc11-8f13-0019bb2ca0a0", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
.Replace("fbd0c892-2373-dc11-8f13-0019bb2ca0a0", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
.Replace("76cd4297-1e31-dc11-95d8-0019bb2ca0a0", "eb892fb0-fe17-e811-80d8-00155d5ce473")
.Replace("cd42bb68-2073-dc11-8f13-0019bb2ca0a0", "dc6077e2-fe17-e811-80d8-00155d5ce473")
.Replace("96b97150-cd45-e111-a3d5-00155d10010f", "1fe8f3f6-fe17-e811-80d8-00155d5ce473")
.ToString();
var newArray = tempStr.Split(',');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.