2013-03-06 35 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