c# – 如何从字符串中删除无效代码点?

我有一个需要提供标准化字符串的例程.但是,进入的数据不一定是干净的,如果字符串包含无效的代码点,String.normalize()会引发ArgumentException.

我想做的只是用诸如’?’的一次性字符替换这些代码点.但是要做到这一点,我需要一种有效的方式来搜索字符串,首先找到它们.什么是好的方法呢?

以下代码工作,但它基本上使用try / catch作为粗略的if语句,所以性能是可怕的.我只是分享它来说明我正在寻找的行为:

private static string ReplaceInvalidCodePoints(string aString,string replacement)
{
    var builder = new StringBuilder(aString.Length);
    var enumerator = StringInfo.GetTextElementEnumerator(aString);

    while (enumerator.MoveNext())
    {
        string nextElement;
        try { nextElement = enumerator.GetTextElement().normalize(); }
        catch (ArgumentException) { nextElement = replacement; }
        builder.Append(nextElement);
    }

    return builder.ToString();
}

(编辑:)我正在考虑将文本转换为UTF-32,以便我可以快速迭代它,并查看每个双字是否对应一个有效的代码点.有没有这样做的功能?如果没有,是否有无效范围列表在那里浮动?

解决方法

看来,唯一的办法就是像你这样做的“手动”.这是一个与您的结果相同的版本,但是速度要快一点(在char.MaxValue中的所有字符串的大约4倍),而不需要不安全的代码.我也简化和评论了我的IsCharacter方法来解释每个选择:
static string ReplaceNonCharacters(string aString,char replacement)
{
    var sb = new StringBuilder(aString.Length);
    for (var i = 0; i < aString.Length; i++)
    {
        if (char.IsSurrogatePair(aString,i))
        {
            int c = char.ConvertToUtf32(aString,i);
            i++;
            if (IsCharacter(c))
                sb.Append(char.ConvertFromUtf32(c));
            else
                sb.Append(replacement);
        }
        else
        {
            char c = aString[i];
            if (IsCharacter(c))
                sb.Append(c);
            else
                sb.Append(replacement);
        }
    }
    return sb.ToString();
}

static bool IsCharacter(int point)
{
    return point < 0xFDD0 || // everything below here is fine
        point > 0xFDEF &&    // exclude the 0xFFD0...0xFDEF non-characters
        (point & 0xfffE) != 0xFFFE; // exclude all other non-characters
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...