【问题标题】:Detect Junk Characters in string检测字符串中的垃圾字符
【发布时间】:2011-08-31 08:10:17
【问题描述】:

我希望允许用户输入字符、数字和特殊字符,但不允许输入 ascii 值大于 127 的垃圾字符(例如 ♠ ♣ 等)。

我有这样的功能

            for (int i = 0; i < value.Length; i++) // value is input string
            {
                if ((int)value[i] < 32 || (int)value[i] > 126)
                {

                         // show error

                 }

            }

这会使代码变慢,因为我必须比较每个字符串及其字符。 任何人都可以提出更好的方法吗?

【问题讨论】:

  • 除非你有一些非常大的字符串,否则这段代码应该很快。我不希望它有任何性能问题。
  • 这可能是使用 Regex 或 LINQ 的好地方。
  • @Tim,for 循环将是最快的。如果它对 OP 来说不够快,那么 Regex 会更糟。
  • @xanatos:我不同意:使用 LINQ 可以让您在整个代码库中编写非常易读的代码,这意味着您可以分析瓶颈发生的位置并微优化只是那些位 i> 如有必要。在许多情况下,LINQ 的简单性实际上使您可以表达比手写更有效的解决方案,仅仅是因为这样做很容易。手动编码有效的解决方案可能最终过于复杂。
  • @Sangram 你写的可能是最快的方法。唯一的事情:您不需要强制转换为 int。

标签: c# string


【解决方案1】:

嗯,一方面你可以让代码更简单

foreach (char c in value)
{
    if (c < 32 || c > 126)
    {
        ...
    }
}

或者使用 LINQ,如果您只需要知道 any 字符是否为非 ASCII:

bool bad = value.Any(c => c < 32 || c > 126);

...但从根本上说,如果不遍历字符串中的每个字符,您将无法检测到非 ASCII 字符...

【讨论】:

  • 任何类似尝试解析方法的东西?就像我们对小数或整数所做的那样
  • 没有char.IsLetter方法吗?
  • 约翰:最快的方法是什么? Linq 或 Loop。我猜是 LINQ ..你建议什么?
  • @Shadow Wizard,char.IsLetter 对数字返回 false,因此不等价于原始测试用例区间 (32, 126)。
  • @Sangram:LINQ 只是在内部循环。您正在测试多少文本?它应该非常快......
【解决方案2】:

您可以制作允许所有所需字符的正则表达式并将其用于每个字符串。我认为这将提高性能。您所要做的就是创建一个正确的正则表达式。

更新:但是,使用 RegEx 不会提高速度,它只会最小化代码行。

【讨论】:

  • 为什么 Regex 应该比 C# 代码更快?正则表达式不会将 O(n) 问题转换为 O(1) 问题。
  • 同意。但它最大限度地减少了(我认为几乎 20%)比较字符二进制文件(加上将其转换为 int)的时间,因为它是预编译的。
  • 不在我的世界里。 Regex 比 Release+NoDebug (pastebin.com/w85vYRpv) 中的慢 5-10 倍
  • @xanatos;我同意代码的结果。直到现在,我在另一个世界。感谢您努力说服我。
猜你喜欢
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 2014-10-05
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多