2010-07-15 33 views
28

Tôi chỉ tự hỏi nếu có một phương pháp trong .NET 2.0 kiểm tra xem một ký tự có thể in được hay không - giống như isprint(int) từ tiêu chuẩn C.Làm cách nào để phát hiện các ký tự không thể in trong .NET?

Tôi tìm thấy Char.IsControl(Char).

Có thể sử dụng cho mục đích này không?

+0

Hãy xác định ý bạn là "Có thể in". Có phải "Coöperate" có thể in được không? Là "協力 す る"? –

+2

Kể từ khi âm sắc và các ký tự Trung Quốc (?) Được hiển thị trên màn hình của tôi, tôi sẽ xem chúng là "có thể in" - tất nhiên! – Baldewin

+0

Sau đó, bạn nên bỏ chọn câu trả lời của JWL_ vì nó nói cả hai đều không được "in được". –

Trả lời

-7
private bool IsPrintableCharacter(char candidate) 
{ 
    return !(candidate < 0x20 || candidate > 127); 
} 
+0

Tại sao câu trả lời này và câu trả lời của JWL_ bao gồm char 127, là DEL theo WikiPedia? Liên kết: http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters –

+3

Rất nhiều ký tự Unicode có thể in, bao gồm năm chữ cái Rumani, không nằm trong 32 ... 127 phạm vi –

33

Bạn có thể muốn sử dụng Char.IsControl(Char). Đó là những gì tôi đang sử dụng. Bạn chắc chắn không muốn sử dụng phương pháp <0x20 vì bất kỳ ký tự phi Latin và hầu hết các ký tự không phải tiếng Anh sẽ vượt 127.

+5

Ngoài các ký tự điều khiển, bạn cũng có thể muốn để loại trừ '0x2028' và' 0x2029'. Nhiều hệ thống cũng coi chúng là không thể in được mặc dù chúng không được phân loại là các ký tự điều khiển. Các ký tự này có thể được lọc theo 'UnicodeCategory.LineSeparator' và' UnicodeCategory.ParagraphSeparator' tương ứng. – MattDavey

+0

Thao tác này sẽ xóa các ký tự chuyển dòng và ký tự dòng. Không sử dụng điều này để kiểm tra các ký tự có thể in hoặc nó sẽ xóa tất cả các dòng mới trong văn bản của bạn. –

2

Nếu bởi in bạn có nghĩa là làm cho cái gì đó - thậm chí nếu có điều gì đó là trống không gian (khoảng trắng), [phủ nhận] Char.IsControl() một mình là không đủ để xác định xem ký tự có thể in được hay không.

  • Nó không phải là đủ ngay cả trong single-byte U+0000-U+00FF Unicode phạm vi (đó là tương thích với ASCII/ISO-8859-1), bởi vì các ký tự ASCII khoảng trắng khác với nhân vật không gian cũng được phân loại dưới dạng ký tự điều khiển, do đó, Char.IsControl('\t')Char.IsControl('\n') cũng báo cáo đúng.

  • Ngoài phạm vi một byte, có các danh mục khác của ký tự không hiển thị phải được nhận dạng.


Một giải pháp cho byte đơn U+0000-U+00FF Unicode phạm vi (đó là tương thích với ASCII/ISO-8859-1):

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

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

Một xấp xỉ của giải pháp cho tất cả ký tự Unicode:

Đáng buồn thay, không có giải pháp đơn giản mà hoàn tất:

  • Một hạn chế cơ bản của một bài kiểm tra dựa trên Char là loại Char chỉ có thể đại diện cho nhân vật lên đến điểm mã U+FFFF, nghĩa là chỉ các ký tự trong cái gọi là BMP (mặt phẳng đa ngôn ngữ cơ bản). Các ký tự bên ngoài BMP - với các điểm mã cao hơn - phải được thể hiện là haiChar trường hợp (được gọi là cặp thay thế).

  • Loại ký tự UnicodeCategory.PrivateUse, như tên cho thấy, không được tiêu chuẩn hóa; ví dụ, U+F8FF trên macOS chứa biểu tượng Apple, trong khi nó không được xác định trên Windows. Vì vậy, có thể chứa các ký tự có thể in và bạn phải xác định động xem chúng có thể in được hay không.

  • Phạm trù UnicodeCategory.Formatchủ yếu chứa các ký tự không render, nhưng có những trường hợp ngoại lệ - xem this table.

    • Bạn có thể mã hóa các ngoại lệ này cho một phiên bản Unicode nhất định, nhưng điều đó cồng kềnh và có thể trở nên lỗi thời theo thời gian.

Do đó, các mã sau đây giả định rằng tất cả nhân vật trong UnicodeCategory.PrivateUseUnicodeCategory.Format là in, trong đó, có nghĩa là ít nhất một số ký tự sẽ được phân loại sai.

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)); 
Các vấn đề liên quan