C#移除字符串中的不可見Unicode字符 案例代碼
C#移除字符串中的不可見Unicode字符
背景
最近發(fā)現(xiàn)某個數(shù)據采集的系統(tǒng)拿下來的數(shù)據,有些字段的JSON被莫名截斷了,導致后續(xù)數(shù)據分析的時候解析JSON失敗。
類似這樣
{"title": "你好或者這樣,多了個雙引號啥的
{"title":""你好"}因為數(shù)據庫是Oracle,起初以為是Oracle這老古董出問題了,結果一番折騰,把每條寫入數(shù)據的SQL語句都拿出來,看起來里面的JSON格式都沒問題。
這也太詭異了吧,看起來沒毛病,但就為啥JSON被隨機截斷呢?
最后我試著把整段SQL放在Rider的 query console 里面執(zhí)行,然后再去數(shù)據庫里讀取這段JSON,居然發(fā)現(xiàn)變成這樣了:
{"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 |
可以看到上面那個 \u0020 在第三行第一列,是一個不可見字符,躲在標題的前面
也就是因為這個 Unicode 字符,Oracle無法正確解析,所以導致了插入數(shù)據的時候錯亂了
所以破案了,就是系統(tǒng)前臺使用人員,在輸入的時候不知道咋滴搞了個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();
搞定。
參考資料
UniCode編碼表及部分不可見字符過濾方案 - https://www.cnblogs.com/fan-yuan/p/8176886.html
補充:C# 字符串與unicode互相轉換實戰(zhàn)案例
代碼如下所示:
/// <summary>
/// 字符串轉Unicode
/// </summary>
/// <param name="source">源字符串</param>
/// <returns>Unicode編碼后的字符串</returns>
public static string String2Unicode(string source)
{
var bytes = Encoding.Unicode.GetBytes(source);
var stringBuilder = new StringBuilder();
for (var i = 0; i < bytes.Length; i += 2)
{
stringBuilder.AppendFormat("\\u{0:x2}{1:x2}", bytes[i + 1], bytes[i]);
}
return stringBuilder.ToString();
}
/// <summary>
/// 字符串轉為UniCode碼字符串
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
public static string StringToUnicode(string s)
{
char[] charbuffers = s.ToCharArray();
byte[] buffer;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < charbuffers.Length; i++)
{
buffer = System.Text.Encoding.Unicode.GetBytes(charbuffers[i].ToString());
sb.Append(String.Format("\\u{0:X2}{1:X2}", buffer[1], buffer[0]));
}
return sb.ToString();
}
/// <summary>
/// Unicode字符串轉為正常字符串
/// </summary>
/// <param name="srcText"></param>
/// <returns></returns>
public static string UnicodeToString(string srcText)
{
string dst = "";
string src = srcText;
int len = srcText.Length / 6;
for (int i = 0; i <= len - 1; i++)
{
string str = "";
str = src.Substring(0, 6).Substring(2);
src = src.Substring(6);
byte[] bytes = new byte[2];
bytes[1] = byte.Parse(int.Parse(str.Substring(0, 2), System.Globalization.NumberStyles.HexNumber).ToString());
bytes[0] = byte.Parse(int.Parse(str.Substring(2, 2), System.Globalization.NumberStyles.HexNumber).ToString());
dst += Encoding.Unicode.GetString(bytes);
}
return dst;
}到此這篇關于C#移除字符串中的不可見Unicode字符 的文章就介紹到這了,更多相關C#移除Unicode字符 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
淺談Visual Studio 2019 Vue項目的目錄結構
這篇文章主要介紹了Visual Studio 2019 Vue項目 目錄結構,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03
WPF利用DrawingContext實現(xiàn)繪制溫度計
這篇文章主要為大家詳細介紹了如何利用WPF和DrawingContext實現(xiàn)繪制溫度計,文中的示例代碼講解詳細,對我們學習或工作有一定幫助,感興趣的小伙伴可以了解一下2022-09-09
Winform開發(fā)中使用下拉列表展示字典數(shù)據的幾種方式
這篇文章介紹了Winform開發(fā)中使用下拉列表展示字典數(shù)據的幾種方式,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09

