C#移除字符串中的不可見Unicode字符
背景
最近發現某個數據采集的系統拿下來的數據,有些字段的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+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0000 | NUL | SOH | STX | ETX | EOT | ENQ | ACK | BEL | BS | HT | LF | VT | FF | CR | SO | SI |
0010 | DLE | DC1 | DC2 | DC3 | DC4 | NAK | SYN | ETB | CAN | EM | SUB | ESC | FS | GS | RS | US |
0020 | ! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | |
0030 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? |
0040 | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O |
0050 | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ |
0060 | ` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o |
可以看到上面那個 \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();
搞定。
參考資料
微信公眾號:「程序設計實驗室」
專注于互聯網熱門新技術探索與團隊敏捷開發實踐,包括架構設計、機器學習與數據分析算法、移動端開發、Linux、Web前后端開發等,歡迎一起探討技術,分享學習實踐經驗。