如何从字符串中剥离非ascii字符?(c#)


当前回答

受philcruz的正则表达式解决方案的启发,我做了一个纯LINQ解决方案

public static string PureAscii(this string source, char nil = ' ')
{
    var min = '\u0000';
    var max = '\u007F';
    return source.Select(c => c < min ? nil : c > max ? nil : c).ToText();
}

public static string ToText(this IEnumerable<char> source)
{
    var buffer = new StringBuilder();
    foreach (var c in source)
        buffer.Append(c);
    return buffer.ToString();
}

这是未经测试的代码。

其他回答

我用了这个正则表达式:

    string s = "søme string";
    Regex regex = new Regex(@"[^a-zA-Z0-9\s]", (RegexOptions)0);
    return regex.Replace(s, "");

这并不是最优的性能,而是一种非常直接的Linq方法:

string strippedString = new string(
    yourString.Where(c => c <= sbyte.MaxValue).ToArray()
    );

缺点是,所有“幸存的”字符首先被放入char[]类型的数组中,然后在字符串构造函数不再使用它后将其丢弃。

string s = "søme string";
s = Regex.Replace(s, @"[^\u0000-\u007F]+", string.Empty);

^是not运算符。它告诉正则表达式去查找所有不匹配的,而不是所有匹配的。\u####-\u####表示匹配的字符。\u0000-\u007F相当于utf-8或unicode中的前128个字符,这些字符总是ascii字符。因此,您匹配每个非ascii字符(因为not),并对所有匹配的字符进行替换。

(正如Gordon Tucker在2009年12月11日21:11的评论中所解释的那样)

我使用这个正则表达式来过滤掉文件名中的坏字符。

Regex.Replace(directory, "[^a-zA-Z0-9\\:_\- ]", "")

这应该是文件名所允许的所有字符。

我发现下面稍微改变的范围对于从数据库中解析注释块很有用,这意味着您不必与制表符和转义字符相争斗,这将导致CSV字段变得混乱。

parsememo = Regex.Replace(parsememo, @"[^\u001F-\u007F]", string.Empty);

如果您希望避免使用其他特殊字符或特殊标点符号,请检查ascii表