删除非ASCII 32到175 C的字符的更好方法#

时间:2012-07-18 14:17:26

标签: c# regex string linq

我需要从字符串中删除不在Ascii范围内的字符,从32到175,其他任何东西都必须删除。

我不清楚RegExp是否是最好的解决方案,而不是使用像.replace()或.remove()这样的东西来修饰每个无效字符或其他东西。

任何帮助将不胜感激。

5 个答案:

答案 0 :(得分:17)

您可以使用

Regex.Replace(myString, @"[^\x20-\xaf]+", "");

此处的正则表达式由一个字符类([...])组成,该字符类包含U + 0020范围内的所有字符 not (类的开头为^)至U + 00AF(32-175,以十六进制表示法表示)。至于正则表达式,这个是相当基本的,但可能会困扰不熟悉它的人。

但你也可以走另一条路:

new string(myString.Where(c => (c >= 32) && (c <= 175)).ToArray());

这可能主要取决于你对阅读感觉更舒服。如果没有太多的正则表达式经验,我会说第二个会更清楚。

一些性能测量,每次10000轮,几秒钟:

2000 characters, the first 143 of which are between 32 and 175
  Regex without +                          4.1171
  Regex with +                             0.4091
  LINQ, where, new string                  0.2176
  LINQ, where, string.Join                 0.2448
  StringBuilder (xanatos)                  0.0355
  LINQ, horrible (HatSoft)                 0.4917
2000 characters, all of which are between 32 and 175
  Regex without +                          0.4076
  Regex with +                             0.4099
  LINQ, where, new string                  0.3419
  LINQ, where, string.Join                 0.7412
  StringBuilder (xanatos)                  0.0740
  LINQ, horrible (HatSoft)                 0.4801

所以是的,我的方法是最慢的:-)。您可能应该使用xanatos的答案并将其包装在一个名称清晰的方法中。对于内联使用或快速和肮脏的事情或性能无关紧要,我可能会使用正则表达式。

答案 1 :(得分:7)

因为我认为如果你不知道如何编写正则表达式,你不应该使用它,特别是对于这么简单的东西:

var sb = new StringBuilder();

foreach (var c in str)
{
    if (c >= 32 && c <= 175)
    {
        sb.Append(c);
    }
}

var str2 = str.ToString();

答案 2 :(得分:3)

使用正则表达式[^\x20-\xAF]+并将其替换为空字符串""

Regex.Replace(str, @"[^\x20-\xAF]+", "");

答案 3 :(得分:1)

如何以这种方式使用linq

string text = (from c in "AAA hello aaaa #### Y world" 
               let i = (int) c where i < 32 && i > 175 select c)
              .Aggregate("", (current, c) => current + c);

答案 4 :(得分:1)

static unsafe string TrimRange(string str, char from, char to)
{
    int count = 0;

    for (int i = 0; i < str.Length; i++)
    {
        char ch = str[i];

        if ((ch >= from) && (ch <= to))
        {
            count++;
        }
    }

    if (count == 0)
        return String.Empty;

    if (count == str.Length)
        return str;

    char * result = stackalloc char[count];

    count = 0;

    for (int i = 0; i < str.Length; i++)
    {
        char ch = str[i];

        if ((ch >= from) && (ch <= to))
        {
            result[count ++] = ch;
        }
    }

    return new String(result, 0, count);
}