61

谁能告诉我 Unicode 可打印字符的范围是多少?[例如 Ascii 可打印字符范围是 \u0020 - \u007f]

4

9 回答 9

23

见,http ://en.wikipedia.org/wiki/Unicode_control_characters

您可能想特别查看 C0 和 C1 控制字符http://en.wikipedia.org/wiki/C0_and_C1_control_codes

wiki 说,C0 控制字符在 U+0000—U+001F 和 U+007F 范围内(与 ASCII 范围相同),C1 控制字符在 U+0080—U+009F 范围内

除了 C 控制字符,Unicode 还有数百个格式化控制字符,例如零宽度非连接符,使字符间距更近,或双向文本控制。这种格式化控制字符比较分散。

更重要的是,你在做什么需要你知道 Unicode 的不可打印字符?很可能,无论您尝试做什么,解决问题的方法都是错误的。

于 2010-09-22T14:27:43.233 回答
18

首先,您应该删除问题中的“UTF8”一词,它不相关(UTF8 只是 Unicode 的编码之一,它与您的问题正交)。

第二:Unicode中“可打印/不可打印”的含义不太清楚。也许您的意思是“图形字符”;如果一个空间是可打印的/图形的,人们甚至可以争论。非图形字符基本上由控制字符组成:范围 0x00-0x0f 加上其他一些分散的字符。

无论如何,绝大多数 Unicode 字符(超过 200.000 个)都是“图形的”。但这当然并不意味着它们可以在您的环境中打印。

在我看来,如果您打算生成一个“随机可打印”的 unicode 字符串来尝试包含所有“可打印”字符,那么这似乎是一个坏主意。

于 2010-09-22T14:55:50.267 回答
16

这是一个古老的问题,但它仍然有效,我认为关于这个主题还有更多有用但简短的说法,而不是现有答案所涵盖的内容。

统一码

Unicode 定义了字符的属性

这些属性之一是具有主要类和子类的“通用类别”。主要类别是字母、标记、标点符号、符号、分隔符和其他。

通过了解角色的属性,您可以决定是否认为它们可在您的特定上下文中打印。

您必须始终记住,诸如“字符”和“可打印”之类的术语通常很困难并且具有有趣的边缘情况。


编程语言支持

一些编程语言有助于解决这个问题。

例如,Go 语言有一个“unicode”包,它提供了许多有用的与 Unicode 相关的功能,包括以下两个:

func IsGraphic(r rune) bool

IsGraphic reports whether the rune is defined as a Graphic by Unicode. Such  
characters include letters, marks, numbers, punctuation, symbols, and spaces, 
from categories L, M, N, P, S, Zs. 

func IsPrint(r rune) bool

IsPrint reports whether the rune is defined as printable by Go. Such  
characters include letters, marks, numbers, punctuation, symbols, and  
the ASCII space character, from categories L, M, N, P, S and the ASCII  
space character. This categorization is the same as IsGraphic except  
that the only spacing character is ASCII space, U+0020.

请注意,它说的是“由 Go 定义为可打印”而不是“由 Unicode 定义为可打印”。就好像 Unicode 的巫师们有一些不敢探究的深度。


可打印

您对 Unicode 了解得越多,就越会意识到人类书写系统的多样性和不可思议的怪异。

特别是一个特定的“字符”是否可打印并不总是显而易见的。

零宽度空间是否可打印?什么时候可以打印断字点?是否有字符的可打印性取决于它们在单词中的位置或与它们相邻的字符?组合字符总是可打印的吗?


脚注

ASCII 可打印字符范围为 \u0020 - \u007f

不,不是。\u007f 是 DEL,通常不被视为可打印字符。例如,它与标有“DEL”的键盘键相关联,其最早目的是命令从某种介质(显示器、文件等)中删除字符。

事实上,许多 8 位字符集有许多不可打印的非连续范围。参见例如 C0 和 C1 控件。

于 2018-11-23T16:19:58.390 回答
6

您应该做的是选择一种字体,然后生成一个列表,其中列出了哪些 Unicode 字符为您的字体定义了字形。您可以使用像 freetype 这样的字体库来测试字形(测试 FT_Get_Char_Index(...) != 0)。

于 2011-05-03T17:48:57.943 回答
1

对@HoldOffHunger 采取相反的方法,列出不可打印字符的范围可能更容易,并用于not测试字符是否可打印。

以 Regex 的风格(因此,如果您想要可打印的字符,请放置 a ^):

[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u2000-\u200F\u2028-\u202F\u205F-\u206F\u3000\uFEFF]

这说明了分隔符空间连接符之类的东西

请注意,与他们的答案不同,这是一个忽略所有非拉丁语言的白名单,这个黑名单不会仅仅因为它们位于带有可打印字符的块中而允许不可打印的字符(他们的答案完全包括Non-Latin, Language Supplement blocks“可打印”,即使它包含东西像'零宽度非连接器'..)。

但是请注意,如果使用此解决方案或任何其他解决方案,例如卫生,您可能想做一些比更换毯子更细微的事情。
可以说在这种情况下,non-breaking spaces 应该更改为space,而不是被删除,并且invisible separator应该有条件地用逗号替换。

然后是无效的字符范围,[尚未]未使用或保留用于编码目的,以及特定于语言的变体选择器..


注意使用正则表达式时,如果默认情况下不是这样,您可以启用 unicode 感知(对于 javascript,它是 via /.../u)。

您可以通过尝试使用一些多字节字符范围创建正则表达式来判断它是否正确。
比如上面,加上\u{E0100}-\u{E01EF}javascript中的无效字符范围:

/[\u0000-\u0008\u000B-\u001F\u007F-\u009F\u2000-\u200F\u2028-\u202F\u205F-\u206F\u3000\uFEFF\u{E0100}-\u{E01EF}]/u

Unicode 正则表达式

如果没有u \u{E0100}-\u{E01EF}equates \uDB40(\uDD00-\uDB40)\uDDEF, not (\uDB40\uDD00)-(\uDB40\uDDEF),并且如果替换,u即使在正则表达式本身中不包含多字节 unicode 时,您也应该始终启用,因为您可能会破坏文本中存在的代理对。

于 2021-09-02T04:49:52.693 回答
0

哪些字符是有效的?

目前,Unicode 被定义为从 开始U+0000和结束于U+10FFFF. 第一个块Basic Latin跨越U+0000U+007F,最后一个块Supplementary Private Use Area-B跨越U+10000010FFFF。如果您想查看所有这些块,请参见此处:Wikipedia.org: Unicode Block;块列表

让我们分解一下拉丁语 Block1 中的有效/无效内容。

拉丁区:TLDR

如果您有兴趣过滤掉任何一个不可见的字符,您需要过滤掉:

  • U+0000U+0008:控制
  • U+000Eto U+001F:设备(即控制)
  • U+007F:删除(控制)
  • U+008Dto U+009F:设备(即控制)

拉丁区:全范围

这是拉丁语块,分成更小的部分......

  • U+0000U+0008:控制
  • U+0009U+000C:空间
  • U+000Eto U+001F:设备(即控制)
  • U+0020: 空间
  • U+0021U+002F:符号
  • U+0030U+0039:数字
  • U+003AU+0040:符号
  • U+0041to U+005A: 大写字母
  • U+005BU+0060:符号
  • U+0061to U+007A: 小写字母
  • U+007BU+007E:符号
  • U+007F:删除(控制)
  • U+0080to U+008C:Latin1-补充符号。
  • U+008Dto U+009F:设备(即控制)
  • U+00A0: 非破坏空间。(即, 
  • U+00A1U+00BF:符号。
  • U+00C0to U+00FF:重音字符。

其他方块

Unicode 以支持非拉丁字符集而闻名,那么这些其他块是什么?这只是一个广泛的概述,请参阅wikipedia.org 页面以获取完整的完整列表。

Latin1 和 Latin1 相关块

  • U+0000to U+007F: 基本拉丁语
  • U+0080to U+00FF: Latin-1 补充
  • U+0100to U+017F: 拉丁语扩展-A
  • U+0180to U+024F: 拉丁语扩展-B

可组合块

U+0250U+036F:3 块。

非拉丁语,语言块

U+0370U+1C7F:55 块。

非拉丁语,语言补充块

U+1C80U+209F:11 个街区。

符号块

U+20A0U+2BFF:22 块。

古代语言块

U+2C00U+2C5F:1 块(格拉哥里)。

语言扩展块

U+2C60U+FFEF:66 块。

特殊块

U+FFF0U+FFFF:1 块(特价)。

于 2021-03-02T20:47:34.720 回答
0

一种方法是将每个字符渲染到纹理并手动检查它是否可见。此解决方案不包括空格。

我编写了这样一个程序,并用它来确定前 471859 个代码点中大约有467241 个可打印字符。我选择了这个数字,因为它涵盖了 Unicode 的所有前 4 个平面,它们似乎包含所有可打印字符。见https://en.wikipedia.org/wiki/Plane_(Unicode)

我很想改进我的程序以生成范围列表,但现在我正在为任何需要立即答案的人使用:

https://editor.p5js.org/SamyBencherif/sketches/_OE8Y3kS9

我发布这个工具是因为我认为这个问题吸引了很多人,他们正在寻找了解可打印范围的稍微不同的应用程序。希望这是有用的,即使它没有完全回答这个问题。

于 2021-05-02T17:07:44.210 回答
-2

在 int 数据类型中,可打印的 Unicode 字符范围(不包括十六进制)是 32 到 126。

于 2020-11-28T07:46:35.220 回答
-7

Unicode,严格术语,没有范围。数字可以无限。

你给的不是 UTF8,它有 1 个字节的 ASCII 字符。

至于范围,我相信没有可打印字符的范围。它总是在进化。检查我上面给出的页面。

于 2010-09-22T14:21:19.017 回答