C# C语言中更好的字符串替换#
有人知道哪一个更适合替换字符串吗 如果我有一个长度不等的字符串集合,其中一些字符串可能需要特殊替换编码的十六进制值(例如=0A、%20…等) 每个字符串的“替换”(可能有多个)将由正则表达式处理,以检测适当的转义十六进制值 哪个效率更高C# C语言中更好的字符串替换#,c#,replace,C#,Replace,有人知道哪一个更适合替换字符串吗 如果我有一个长度不等的字符串集合,其中一些字符串可能需要特殊替换编码的十六进制值(例如=0A、%20…等) 每个字符串的“替换”(可能有多个)将由正则表达式处理,以检测适当的转义十六进制值 哪个效率更高 只需在集合中的每个字符串上运行替换,即可通过暴力确保完成所有需要的替换 如果需要替换,则执行测试,并仅在需要替换的字符串上运行替换 我在C#工作 更新 回答和评论中的一些附加信息 这主要用于从二维码加载的VCARD处理 我目前有一个正则表达式,它使用捕获组从每个
对我来说,更合理的做法是加载我的捕获组,然后捕获版本,并在每次匹配时进行适当的解码替换,当您仅进行替换时,如果没有匹配,则执行速度会稍慢,因为替换会进行额外的检查(例如) 如果没有找到匹配项,Regex.Replace会返回输入,因此这里没有内存问题
Match match = regex.Match(input, startat);
if (!match.Success)
{
return input;
}
当存在匹配时,regex.match将在执行该操作时激发两次,在replace执行该操作时再次激发。这意味着检查和更换的执行速度会慢一些
因此,您的结果将基于
- 你期待很多比赛还是很多失误
- 当存在匹配项时,
将在额外的参数检查上运行两次这一事实如何?我猜可能会的Regex.Match
outputBuffer:=新的StringBuilder
索引:=0
最大:=输入长度
而指数
如果使用字符串替换,则使用可能比使用string.Replace更好。(替换时不会创建许多临时字符串…)(代表问题作者发布)
从一些参与进来的优秀人士那里获得了一些灵感,我成功地隔离并测试了有问题的代码
在这两种情况下,我都有一个解析器正则表达式来处理vcard的每一行,还有一个解码正则表达式来处理捕获任何编码的十六进制数
我突然想到,不管我是否使用string.Replace,我仍然必须依赖Decode正则表达式来获取可能的替换十六进制代码
我运行了几个不同的场景以查看数字是否会发生变化;包括:将正则表达式MatchCollection强制转换为字典以消除Match对象的复杂性,并将解码正则表达式投影到一个不同的简单匿名对象集合中,该对象具有简单字符串的新旧字符串值。替换调用
最后,不管我如何使用字符串对测试进行处理。Replace它很接近,但总是比让解码的正则表达式执行它的Replace操作慢
最接近的是大约12%的速度差异
最后,对于那些好奇的人来说,这就是最终获胜的代码块
var ParsedCollection = Parser.Matches(UnfoldedEncodeString).Cast<Match>().Select(m => new
{
Field = m.Groups["FIELD"].Value,
Params = m.Groups["PARAM"].Captures.Cast<Capture>().Select(c => c.Value),
Encoding = m.Groups["ENCODING"].Value,
Content = m.Groups["ENCODING"].Value.FirstOrDefault == 'Q' ? QuotePrintableDecodingParser.Replace(m.Groups["CONTENT"].Value, me => Convert.ToChar(Convert.ToInt32(me.Groups["HEX"].Value, 16)).ToString()) : m.Groups["CONTENT"].Value,
Base64Content = ((m.Groups["ENCODING"].Value.FirstOrDefault() == 'B') ? Convert.FromBase64String(m.Groups["CONTENT"].Value.Trim()) : null)
});
var ParsedCollection=Parser.Matches(UnfoldedEncodeString).Cast().Select(m=>new
{
字段=m.Groups[“字段”]。值,
Params=m.Groups[“PARAM”].Captures.Cast().Select(c=>c.Value),
Encoding=m.Groups[“Encoding”].值,
Content=m.Groups[“ENCODING”].Value.FirstOrDefault=='Q'?QuotePrintableDecodingParser.Replace(m.Groups[“Content”].Value,me=>Convert.ToChar(Convert.ToInt32(me.Groups[“HEX”].Value,16)):m.Groups[“Content”].Value,
Base64Content=((m.Groups[“ENCODING”].Value.FirstOrDefault()='B')?Convert.FromBase64String(m.Groups[“CONTENT”].Value.Trim()):null)
});
所有字段、它们的值、任何参数以及解码后的两个最常见的编码都被投射到一个包装精美的匿名对象中
另一方面,从字符串到解析和解码的匿名对象,只需1000纳秒多一点(感谢LINQ和扩展方法)(基于100000个测试和大约4000个长度的VCARD).当您测试它时,您的结果是什么?顺便说一句,我的猜测是不要测试总是替换我不知道如果没有找到匹配项,.net正则表达式引擎是否会返回原始实例。如果没有,它会给GC带来更大的压力,与增加的CPU成本相比,这是一个不小的影响。因此,一个简单的微型平台ark可能不会删除它。@ConradFrix我倾向于同意,.NET framework经过了大量优化,我想在替换之前添加一个测试会比较慢……但是,如果不进行替换,它会返回完全相同的字符串实例吗?我想测试很简单。内存占用可能是一个问题。听起来像是要对某个字符串进行url编码考虑使用内置的方法,而不是自己滚动。如果你有足够的时间来寻找,当然你可以花半个小时写一些代码来测试和我。
outputBuffer := new StringBuilder
index := 0
max := input.Length
while index < max
if input[ index ] == '%'
&& IsHexDigit( input[ index + 1 ] )
&& IsHexDigit( input[ index + 2 ] )
outputBuffer.Append( ( char )int.Parse( input.Substring( index + 1, 2 )
index += 3
continue
else
outputBuffer.Append( input[ index ] )
index ++;
continue
var ParsedCollection = Parser.Matches(UnfoldedEncodeString).Cast<Match>().Select(m => new
{
Field = m.Groups["FIELD"].Value,
Params = m.Groups["PARAM"].Captures.Cast<Capture>().Select(c => c.Value),
Encoding = m.Groups["ENCODING"].Value,
Content = m.Groups["ENCODING"].Value.FirstOrDefault == 'Q' ? QuotePrintableDecodingParser.Replace(m.Groups["CONTENT"].Value, me => Convert.ToChar(Convert.ToInt32(me.Groups["HEX"].Value, 16)).ToString()) : m.Groups["CONTENT"].Value,
Base64Content = ((m.Groups["ENCODING"].Value.FirstOrDefault() == 'B') ? Convert.FromBase64String(m.Groups["CONTENT"].Value.Trim()) : null)
});