• C#如何过滤不可见Unicode字符
  • 发布于 2个月前
  • 430 热度
    0 评论
  • 且醉
  • 0 粉丝 44 篇博客
  •   
一.背景
最近发现某个数据采集的系统拿下来的数据,有些字段的JSON被莫名截断了,导致后续数据分析的时候解析JSON失败。
类似这样
{"title": "你好堆代码
或者这样,多了个双引号啥的
{"title":""你好堆代码"}
因为数据库是Oracle,起初以为是Oracle这老古董出问题了,结果一番折腾,把每条写入数据的SQL语句都拿出来,看起来里面的JSON格式都没问题。这也太诡异了吧,看起来没毛病,但就为啥JSON被随机截断呢?最后我试着把整段SQL放在Rider的 query console 里面执行,然后再去数据库里读取这段JSON,居然发现变成这样了:
{"title":"?你好堆代码"}
啊这,看到这个大大的问号,立刻就能知道这个“你好堆代码”里面不止是这两个字,肯定含有不可见的Unicode字符。然后把这段JSON复制出来,用16进制模式打开,果然看到在“你好”前面有一个 \u0020 的字符…

二.Unicode码表
0000-007F:C0控制符及基本拉丁文 (C0 Control and Basic Latin)
0080-00FF:C1控制符及拉丁文补充-1 (C1 Control and Latin 1 Supplement)
0100-017F:拉丁文扩展-A (Latin Extended-A)
0180-024F:拉丁文扩展-B (Latin Extended-B)
0250-02AF:国际音标扩展 (IPA Extensions)
02B0-02FF:空白修饰字母 (Spacing Modifiers)
……
这里再附上部分 Unicode 表格

可以看到上面那个 \u0020 在第三行第一列,是一个不可见字符,躲在标题的前面,也就是因为这个 Unicode 字符,Oracle无法正确解析,所以导致了插入数据的时候错乱了,所以破案了,就是系统前台使用人员,在输入的时候不知道咋滴搞了个Unicode字符进去…

解决方法就是我这边采集的时候再做一次过,没想到C#要搞个过滤 Unicode 还挺折腾的,资料太了,最后还是参考了Java的资料搞的。

三.代码
代码如下:
写了个扩展方法来过滤
public static class StringExt { 
    // 堆代码 www.duidaima.com
    // 控制字符
    private static readonly Regex ControlCharRegex = new Regex(@"[\p{C}]", RegexOptions.Compiled);

    /// <summary>
    /// 移除控制字符
    /// </summary>
    public static string RemoveControlChars(this string text) {
        return ControlCharRegex.Replace(text, string.Empty);
    }
}
要使用的时候就这样
var outStr = "带有Unicode的字符串".RemoveControlChars();
搞定。
用户评论