如何在.NET中检测不可打印的字符?

问题描述 投票:34回答:4

我只是想知道.NET 2.0中是否有一种方法可以检查字符是否可打印 - 类似于标准C中的isprint(int)

我找到了Char.IsControl(Char)

这可以用于此目的吗?

c# .net vb.net
4个回答
35
投票

您可能想要使用Char.IsControl(Char)。这就是我正在使用的。你绝对不想使用<0x20方法,因为任何非拉丁字符和大多数非英文字符都将高于127。


6
投票

如果通过可打印你的意思是渲染某些东西 - 即使某些东西是空白(空白),单独[否定] Char.IsControl()还不足以确定角色是否可打印。

  • 即使在单字节U+0000 - U+00FF Unicode范围(与ASCII / ISO-8859-1兼容)中也是不够的,因为除了空格字符之外的ASCII空白字符也被归类为控制字符,因此Char.IsControl('\t')Char.IsControl('\n')报告也是如此。
  • 除了单字节范围之外,还必须识别其他类别的非渲染字符。

单字节U+0000 - U+00FF Unicode范围的解决方案(与ASCII / ISO-8859-1兼容):

  // Sample input char.
  char c = (char)0x20; // space

  var isPrintable = ! Char.IsControl(c) || Char.IsWhiteSpace(c);

所有Unicode字符的解决方案的近似值:

遗憾的是,没有完整的简单解决方案:

  • 基于Char的测试的基本限制是类型Char只能表示直到代码点U+FFFF的字符,即,仅表示所谓的BMP(基本多语言平面)中的字符。 BMP之外的字符 - 具有更高的代码点 - 必须表示为两个Char实例(所谓的代理对)。
  • 顾名思义,UnicodeCategory.PrivateUse类别的字符不是标准化的;例如,macOS上的U+F8FF包含Apple符号,而在Windows上未定义。因此它可能包含可打印字符,您必须动态确定它们是否可打印。
  • UnicodeCategory.Format类别主要包含非渲染字符,但也有例外 - 请参阅this table。 对于给定版本的Unicode标准,您可以对这些异常进行硬编码,但这很麻烦,并且可能会随着时间的推移而过时。

因此,以下代码假定UnicodeCategory.PrivateUseUnicodeCategory.Format中的所有字符都是可打印的,这意味着至少某些字符将被错误分类。

using System;
using System.Linq;
using System.Globalization;

// ...

  // Sample input char.
  char c = (char)0x20; // space

  // The set of Unicode character categories containing non-rendering,
  // unknown, or incomplete characters.
  // !! Unicode.Format and Unicode.PrivateUse can NOT be included in
  // !! this set, because they may (private-use) or do (format)
  // !! contain at least *some* rendering characters.
  var nonRenderingCategories = new UnicodeCategory[] {
    UnicodeCategory.Control,
    UnicodeCategory.OtherNotAssigned,
    UnicodeCategory.Surrogate };

  // Char.IsWhiteSpace() includes the ASCII whitespace characters that
  // are categorized as control characters. Any other character is
  // printable, unless it falls into the non-rendering categories.
  var isPrintable = Char.IsWhiteSpace(c) ||
    ! nonRenderingCategories.Contains(Char.GetUnicodeCategory(c));

1
投票

除了Char.IsControlChar()之外,还有其他几个函数可用于确定给定char值的类别:

  • IsLetter()
  • ISNUMBER()
  • IsDigit()
  • IsLetterOrDigit()
  • IsSymbol()
  • IsPunctuation()
  • 并将isSeparator()
  • IsWhiteSpace()

如果您拥有的是“传统的ASCII文本”文件,并且您想使用提供的函数,则表达式为:

(Char.IsLetterOrDigit(ch) || Char.IsPunctuation(ch) || Char.IsSymbol(ch) || (ch==' '))

应该管用。

现在,如果您正在使用Unicode,那么您正在打开罐头或蠕虫。即使在当天,无论空间是可打印的还是不可打印的,都可以进行解释(因此isprint()和isgraph()函数)。见this related question and answers about "printable" unicode characters


-9
投票
private bool IsPrintableCharacter(char candidate)
{
    return !(candidate < 0x20 || candidate > 127);
}
© www.soinside.com 2019 - 2024. All rights reserved.