返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
C#

C#移除字符串中的不可见Unicode字符

背景 最近发现某个数据采集的系统拿下来的数据,有些字段的JSON被莫名截断了,导致后续数据分析的时候解析JSON失败。 类似这样 {title: 你好 或者这样,多了个双引号啥的 {title:你好} 因为数据库是Oracle,起初以为是Oracle这老古董出问题了,结果一番折腾,把每条写入数据的SQL语句都拿出来,看起来里面的JSON格式都没问题。 这也太诡异了吧,看起来没毛病,但就为啥JSON

曦远 (DealiAxy)约 17 分钟
目录4 个章节

背景

最近发现某个数据采集的系统拿下来的数据,有些字段的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 表格

U+0123456789ABCDEF
0000NULSOHSTXETXEOTENQACKBELBSHTLFVTFFCRSOSI
0010DLEDC1DC2DC3DC4NAKSYNETBCANEMSUBESCFSGSRSUS
0020!"#$%&'()*+,-./
00300123456789:;<=>?
0040@ABCDEFGHIJKLMNO
0050PQRSTUVWXYZ[\]^_
0060`abcdefghijklmno

可以看到上面那个 \u0020 在第三行第一列,是一个不可见字符,躲在标题的前面

也就是因为这个 Unicode 字符,Oracle无法正确解析,所以导致了插入数据的时候错乱了

所以破案了,就是系统前台使用人员,在输入的时候不知道咋滴搞了个Unicode字符进去…

解决方法就是我这边采集的时候再做一次过滤…

没想到C#要搞个过滤 Unicode 还挺折腾的,资料太少…

最后还是参考了Java的资料搞的。= =...

代码

代码如下

写了个扩展方法来过滤

public static class StringExt { 
    // 控制字符
    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();

搞定。

参考资料

_EOF_

C#移除字符串中的不可见Unicode字符

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

C#学习(一)委托的概念和使用

前言 C#学习系列是根据我以前的笔记整理出来复习,顺便发一下文章做个记录。 先引用一个介绍: C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。 根据使用其他

2021-12-18 · C# · 约 1 分钟

C#实现解析Markdown文档并处理图片链接

前言 又是好久没写博客了 其实也不是没写,是最近在「做一个博客」,从2月21日开始,大概一个多星期的时间,疯狂刷进度,边写代码边写了一整系列的博客开发笔记,目前为止已经写了16篇了,然后上3月之后工作有点忙~~加上有点沉迷原神~~,然后进度就暂时慢下来了 事实证明做什么事情一旦停下来就会产生惰性,于是停了这么久,我终于下定决心继续更新! 这次开发的博客用的是C#语言,搭配.netcore技术栈;前

2022-03-19 · C# · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…