2013-03-06 69 views
15

我的問題:刪除字符串中的隱藏字符

我有一個.NET應用程序通過電子郵件發送新聞簡報。當在Outlook中查看通訊時,Outlook將顯示一個問號而不是隱藏的字符,它無法識別。這些隱藏的角色來自最終用戶,他們複製和粘貼構成新聞通訊的HTML並將其提交。如果c#trim()發生在字符串的末尾或開頭,它將刪除這些隱藏的字符。當通訊在Gmail中被查看時,gmail會很好地忽略它們。將這些隱藏字符粘貼到單詞文檔中時,打開「顯示段落標記和隱藏符號」選項時,符號在較大的矩形內顯示爲一個矩形。此外,組成通訊的文本可以是任何語言,因此接受Unicode字符是必須的。我嘗試過循環字符串來檢測字符,但循環無法識別它並通過它。同時要求最終用戶在提交之前先將html粘貼到記事本中,這是不可能的。

我的問題:
如何使用C#檢測並消除這些隱藏的字符?

+0

把這裏的例子.. – 2013-03-06 22:22:46

+0

例無效值會不錯。我猜測它的unicode字符串在ascii文本中,但這只是一個猜測。 – 2013-03-06 22:25:33

+0

正則表達式,只允許字母數字 – 2013-03-06 22:25:36

回答

42

您可以從您輸入的字符串像這樣的東西刪除所有控制字符。

或者,如果你想保留的字母和數字而已,你還可以使用IsLetterIsDigit功能:

string output = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray()); 
+0

謝謝,我會試試這個。我會嘗試對它進行編碼並立即將其解碼,以查看隱藏的char是否被刪除。 – bradley4 2013-03-07 00:15:04

+0

HtmlEncode/Decode不會刪除任何字符,不知道您推薦如何使用它。 – 2013-03-07 01:05:22

+0

@AlexeiLevenkov是的,對不起,我誤解了這個問題......我會相應地更新我的答案。 – 2013-03-07 07:32:19

1

如果您知道這些字符是可以使用string.Replace

newString = oldString.Replace("?", ""); 

,其中 「?」代表你想脫光的角色。

這種方法的缺點是,如果您想刪除多個字符,則需要重複進行此調用。對於IsControl()方法

string input; // this is your input string 
string output = new string(input.Where(c => !char.IsControl(c)).ToArray()); 

Here is the documentation

+0

謝謝,但我不能使用這種方法,因爲我不知道隱藏的字符是什麼。它只是作爲一個問號出現在展望中。 – bradley4 2013-03-07 00:16:45

+1

+1。 @ bradley4,如果你不知道要刪除什麼(或要保留什麼),你如何期望人們回答你的問題? – 2013-03-07 01:04:22

3

你可以這樣做:

var hChars = new char[] {...}; 
var result = new string(yourString.Where(c => !hChars.Contains(c)).ToArray()); 
+0

謝謝,但我不能使用這種方法,因爲我不知道隱藏的字符是什麼。它只是作爲一個問號出現在展望中。 – bradley4 2013-03-07 00:16:01

0

它已經有一段時間,但這還沒有得到回答。

如何在發送代碼中包含HMTL內容?如果您正在從文件中讀取它,請檢查文件編碼。如果您使用帶簽名的UTF-8(名稱在編輯器之間略有不同),則可能會在郵件開始時導致奇怪的字符。

12

我通常使用這個正則表達式來替換所有不可打印的字符。

順便說一句,大多數人認爲製表符,換行符和回車符是不可打印的字符,但對我來說卻不是。

因此,這裏的表達式:

string output = Regex.Replace(input, @"[^\u0009\u000A\u000D\u0020-\u007E]", "*"); 
  • ^意味着如果它是下列任何一種:
  • \u0009被標籤
  • \u000A被換行
  • \u000D是回車
  • \u0020-\u007E意味着從水療中心的一切ce到~ - 即ASCII中的所有內容。

請參閱ASCII table如果您想進行更改。記住它會剝離每個非ASCII字符。

要測試上面,你可以創建一個像這樣的字符串自己:

string input = string.Empty; 

    for (int i = 0; i < 255; i++) 
    { 
     input += (char)(i); 
    } 
+2

我認爲第一個^反轉了這個集合,而其他的^不應該在那裏(將會從輸出中排除^)。 – Matt 2016-06-29 21:17:25

0

字符串輸出=新的字符串(!input.Where(C => char.IsControl(C))ToArray的()) ; 這一定會解決問題。我曾在一個字符串中的非打印替代characer(ASCII 26),這是導致我的應用程序,以打破這行代碼刪除字符

2

對我有什麼最好的工作是:

string result = new string(value.Where(c => char.IsLetterOrDigit(c) || (c >= ' ' && c <= byte.MaxValue)).ToArray()); 

我在哪裏」確保字符是任何字母或數字,這樣我就不會忽略任何非英文字母,或者如果它不是字母,我會檢查它是否大於或等於空格的ascii字符以確保我忽略某些字母控制字符,這可以確保我不會忽略標點符號。

一些建議使用IsControl檢查字符是否不可打印,但忽略了從左到右的標記。

3
new string(input.Where(c => !char.IsControl(c)).ToArray()); 

IsControl錯過了一些控制字符,如從左到右的標記(LRM)(通常在執行復制粘貼時隱藏在字符串中的字符)。如果你確定你的字符串只有數字和數字,那麼你可以使用IsLetterOrDigit

new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray()) 

如果字符串包含特殊字符,然後

new string(input.Where(c => c < 128).ToArray()) 
+0

不幸的是,從我的單元測試中,最後一個建議('new string(input.Where(c => c <128).ToArray())')也會去掉重音字符。例如,「Siñalizacíon」將成爲「Sializacon」。 – 2018-01-31 20:15:04