【发布时间】:2012-02-04 17:30:33
【问题描述】:
我有一个需要提供标准化字符串的例程。但是,传入的数据不一定是干净的,如果字符串包含无效的代码点,则 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,以便我可以快速迭代它并查看每个 dword 是否对应于一个有效的代码点。有没有可以做到这一点的功能?如果没有,是否有一个无效范围列表?
【问题讨论】:
-
请注意,由于代理对,不可能简单地查看任意的
DWORD并判断它是否是有效的代码点。 -
UTF-32 不使用代理对。
-
您是如何收到这些不良数据的?如果您使用
Encoding类阅读它,则默认情况下应删除这些字符。 -
与@Porges 的问题相关,如果是您的代码从源(例如文件、网络、大型数据库字段)创建字符串,那么可以将逻辑进一步向下推并处理早期阶段,吞吐量可能更高。
-
谢谢。它已经尽可能地向前推进,与框架接口相抵触。这让我无法完全控制字符串的出处,所以我无法逃避可能会出现糟糕输入的计划。