从字符串中删除隐藏的字符

bra*_*ey4 25 .net c# string hidden-characters

我的问题:

我有一个.NET应用程序,通过电子邮件发送新闻稿.在Outlook中查看简报时,outlook会显示一个问号,代替无法识别的隐藏字符.这些隐藏的角色来自最终用户,他们将构成简报的html复制并粘贴到表单中并提交.如果c#trim()出现在字符串的结尾或开头,则会删除这些隐藏的字符.在gmail中查看简报时,gmail会忽略它们.当粘贴word文档中的这些隐藏字符并打开"显示段落标记和隐藏符号"选项时,符号在较大的矩形内显示为一个矩形.组成简报的文本也可以是任何语言,因此接受Unicode字符是必须的.我已经尝试循环遍历字符串以检测字符,但循环不识别它并通过它.还要求最终用户在提交之前先将html粘贴到记事本中是不可能的.

我的问题:
如何使用C#检测并消除这些隐藏的字符?

Yan*_*eau 69

您可以使用以下内容从输入字符串中删除所有控制字符:

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

这是IsControl()方法的文档.

或者如果您只想保留字母和数字,您还可以使用IsLetterIsDigit功能:

string output = new string(input.Where(c => char.IsLetter(c) || char.IsDigit(c)).ToArray());
Run Code Online (Sandbox Code Playgroud)

  • 我不知道为什么,但是Char.IsControl为从左到右的标记返回false (4认同)
  • @IgorMeszaros LRM 是一个“格式”字符,但幸运的是 C# 有一个 GetUnicodeCategory(char c) 方法,可以识别任何字符的类别。`string clean = new string(e.Value.Where(c => char.GetUnicodeCategory(c) != UnicodeCategory.Format).ToArray());` 可以很好地删除 LRM。 (3认同)
  • @YannickBlondeau 也将删除标点符号和特殊字符“£$%^”等,所以在我看来最好的解决方案是 2 的组合,或者我添加的答案 (2认同)

Mub*_*har 21

我通常使用此正则表达式来替换所有不可打印的字符.

顺便说一句,大多数人认为标签,换行和回车是不可打印的字符,但对我来说它们不是.

所以这是表达式:

string output = Regex.Replace(input, @"[^\u0009\u000A\u000D\u0020-\u007E]", "*");
Run Code Online (Sandbox Code Playgroud)
  • ^ 表示是否为以下任何一项:
  • \u0009 是标签
  • \u000A 是换行的
  • \u000D 是回车
  • \u0020-\u007E意味着从空间到一切~- 即ASCII中的所有东西.

如果要进行更改,请参阅ASCII表.请记住,它会剥离每个非ASCII字符.

要测试上面你可以自己创建一个字符串,如下所示:

    string input = string.Empty;

    for (int i = 0; i < 255; i++)
    {
        input += (char)(i);
    }
Run Code Online (Sandbox Code Playgroud)

  • 我认为第一个^反转集合,而另一个^ s不应该在那里(将从输出中排除^). (3认同)

Igo*_*ros 7

最适合我的是:

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

在我确保字符是任何字母或数字的地方,这样我就不会忽略任何非英文字母,或者如果它不是一个字母,我会检查它是否是一个大于或等于 Space 的 ascii 字符以确保我忽略了一些控制字符,这确保我不会忽略标点符号。

有些人建议使用 IsControl 检查字符是否不可打印,但例如忽略从左到右标记。


sha*_*aja 6

new string(input.Where(c => !char.IsControl(c)).ToArray());
Run Code Online (Sandbox Code Playgroud)

IsControl错过了一些控制字符,如从左到右标记(LRM)(在复制粘贴时通常隐藏在字符串中的字符).如果您确定您的字符串只有数字和数字,那么您可以使用IsLetterOrDigit

new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray())
Run Code Online (Sandbox Code Playgroud)

如果你的字符串有特殊字符,那么

new string(input.Where(c => c < 128).ToArray())
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,从我的单元测试来看,最后一个建议(`new string(input.Where(c =&gt; c &lt; 128).ToArray())`)也会删除重音字符。例如,“Siñalizacíon”将变为“Sializacon”。 (2认同)