C#:从字符串中删除常见的无效字符:改进此算法
考虑从字符串中删除无效字符的要求。 只需要删除字符并替换为blank或string.Empty
。
char[] BAD_CHARS = new char[] { '!', '@', '#', '$', '%', '_' }; //simple example foreach (char bad in BAD_CHARS) { if (someString.Contains(bad)) someString = someString.Replace(bad.ToString(), string.Empty); }
我真的很喜欢这样做:
if (BAD_CHARS.Any(bc => someString.Contains(bc))) someString.Replace(bc,string.Empty); // bc is out of scope
问题:您对重构此算法或任何更简单,易于阅读,高性能,可维护的算法有什么建议吗?
char[] BAD_CHARS = new char[] { '!', '@', '#', '$', '%', '_' }; //simple example someString = string.Concat(someString.Split(BAD_CHARS,StringSplitOptions.RemoveEmptyEntries));
应该做的伎俩(抱歉我的手机上有任何较小的语法错误)
我不知道它的可读性,但正则表达式可以满足您的需要:
someString = Regex.Replace(someString, @"[!@#$%_]", "");
string
类是不可变的(尽管是引用类型),因此它的所有静态方法都被设计为返回一个新的 string
变量。调用 – 好像你解决了这个问题。 someString.Replace
而不将其分配给任何东西将不会对您的程序产生任何影响。
您建议的算法的主要问题是它重复分配许多新的string
变量,可能会导致性能大幅下降。 LINQ在这里并没有真正的帮助。 (在我看来,我不会使代码明显缩短,当然也不会更具可读性。)
请尝试以下扩展方法。 关键是使用StringBuilder
,这意味着在执行期间只为结果分配了一个内存块。
private static readonly HashSet badChars = new HashSet { '!', '@', '#', '$', '%', '_' }; public static string CleanString(this string str) { var result = new StringBuilder(str.Length); for (int i = 0; i < str.Length; i++) { if (!badChars.Contains(str[i])) result.Append(str[i]); } return result.ToString(); }
该算法还利用.NET 3.5’HashSet’类为O(1)
查找检测错误char的查找时间。 这使得整体算法O(n)
而不是您发布的算法的O(nm)
( m
是坏字符的数量); 如上所述,内存使用情况也好得多。
这个比HashSet
快。 此外,如果您必须经常执行此操作,请考虑我在此处提出的此问题的基础。
private static readonly bool[] BadCharValues; static StaticConstructor() { BadCharValues = new bool[char.MaxValue+1]; char[] badChars = { '!', '@', '#', '$', '%', '_' }; foreach (char c in badChars) BadCharValues[c] = true; } public static string CleanString(string str) { var result = new StringBuilder(str.Length); for (int i = 0; i < str.Length; i++) { if (!BadCharValues[str[i]]) result.Append(str[i]); } return result.ToString(); }
需要考虑的事项 – 如果这是用于密码(比如说),你想要扫描并保留好的角色 ,并假设其他一切都不好。 它更容易正确过滤或好事,然后尝试猜测所有坏事。
对于每个字符如果字符是好的 – >保留它(复制到输出缓冲区,无论如何。)
杰夫
如果您仍想以LINQy方式执行此操作:
public static string CleanUp(this string orig) { var badchars = new List() { '!', '@', '#', '$', '%', '_' }; return new string(orig.ToCharArray().Where(c => !badchars.Contains(c)).ToArray()); }
你为什么真的喜欢这样做? 代码绝对不简单,你只是强迫查询扩展方法进入你的代码。
另外, Contains
检查在概念上和从性能角度看都是多余的。 无论如何, Contains
必须贯穿整个字符串,你也可以为每个字符调用Replace(bad.ToString(), string.Empty)
并忘记它是否真正存在。
当然,正则表达式总是一种选择,并且在这种情况下可能更具性能(如果不是更不清楚)。
额外提示:如果您不想记住对文件无效的char
数组,可以使用Path.GetInvalidFileNameChars()
。 如果你想要Paths,那就是Path.GetInvalidPathChars
private static string RemoveInvalidChars(string str) { return string.Concat(str.Split(Path.GetInvalidFileNameChars(), StringSplitOptions.RemoveEmptyEntries)); }
这很干净。 将其限制为有效字符,而不是删除无效字符。 您可能应该将其拆分为常量:
上述就是C#学习教程:C#:从字符串中删除常见的无效字符:改进此算法分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
string clean = new string(@"Sour!ce Str&*(@ing".Where(c => @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.".Contains(c)).ToArray()
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1007182.html