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')
và 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.Format
chủ 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.PrivateUse
và UnicodeCategory.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));
Hãy xác định ý bạn là "Có thể in". Có phải "Coöperate" có thể in được không? Là "協力 す る"? –
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
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". –