目前尚不清楚您在这里的实际和确切含义。如果您打算按数字玩,那么Unicode 技术标准 #18 关于Unicode 正则表达式的附录 C给出了具体建议,即“可打印”代码点被定义为具有该print
属性的任何代码点,其中该属性被定义为是
\p{print}
方法[[\p{graph}\p{blank}]&&[^\p{gc=Control}]]
\p{graph}
方法[^\p{Whitespace}\p{gc=Control}\p{gc=Surrogate}\p{gc=Unassigned}]
\p{blank}
方法[\p{Whitespace}&&[^\N{LF}\N{VT}\N{FF}\N{CR}\N{NEL}\p{gc=Line_Separator}\{gc=Paragraph_Separator}]
或者,作为 Java 1.7Pattern
类的文档,假设您编译模式时启用了 new-to-Java7 Pattern.UNICODE_CHARACTER_CLASS标志:
\p{Graph}
一个可见的字符:[^\p{IsWhite_Space}\p{gc=Cc}\p{gc=Cs}\p{gc=Cn}]
\p{Print}
可打印字符:[\p{Graph}\p{Blank}&&[^\p{Cntrl}]]
\p{Blank}
空格或制表符:[\p{IsWhite_Space}&&[^\p{gc=Zl}\p{gc=Zp}\x0a\x0b\x0c\x0d * \x85]]
\p{Cntrl}
控制字符:\p{gc=Cc}
\p{XDigit}
十六进制数字:[\p{gc=Nd}\p{IsHex_Digit}]
\p{Space}
空白字符:\p{IsWhite_Space}
关于“可打印”字符
如果您只是使用一些合理的东西,例如 Java 的(?U)\p{print}
模式属性(或类中的等价物Character
),那么您仍然需要做出一些“有趣”的决定。
考虑以下每个代码点:
U+000007 gc=Cc columns=0 print=0 graph=0 ALERT
U+000008 gc=Cc columns=0 print=0 graph=0 BACKSPACE
U+000009 gc=Cc columns=0 print=0 graph=0 CHARACTER TABULATION
U+00000C gc=Cc columns=0 print=0 graph=0 FORM FEED (FF)
U+00000D gc=Cc columns=0 print=0 graph=0 CARRIAGE RETURN (CR)
U+000020 gc=Zs columns=1 print=1 graph=0 SPACE
U+000021 gc=Po columns=1 print=1 graph=1 EXCLAMATION MARK
U+000041 gc=Lu columns=1 print=1 graph=1 LATIN CAPITAL LETTER A
U+000061 gc=Ll columns=1 print=1 graph=1 LATIN SMALL LETTER A
U+000080 gc=Cc columns=0 print=0 graph=0 PADDING CHARACTER
U+000085 gc=Cc columns=0 print=0 graph=0 NEXT LINE (NEL)
U+00008D gc=Cc columns=0 print=0 graph=0 REVERSE LINE FEED
U+0000AB gc=Pi columns=1 print=1 graph=1 LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
U+0000AD gc=Cf columns=0 print=1 graph=1 SOFT HYPHEN
U+0002B0 gc=Lm columns=1 print=1 graph=1 MODIFIER LETTER SMALL H
U+0002C6 gc=Lm columns=1 print=1 graph=1 MODIFIER LETTER CIRCUMFLEX ACCENT
U+000302 gc=Mn columns=0 print=1 graph=1 COMBINING CIRCUMFLEX ACCENT
U+00036A gc=Mn columns=0 print=1 graph=1 COMBINING LATIN SMALL LETTER H
U+001100 gc=Lo columns=2 print=1 graph=1 HANGUL CHOSEONG KIYEOK
U+002028 gc=Zl columns=0 print=0 graph=0 LINE SEPARATOR
U+002029 gc=Zp columns=0 print=0 graph=0 PARAGRAPH SEPARATOR
U+00202B gc=Cf columns=0 print=1 graph=1 RIGHT-TO-LEFT EMBEDDING
U+00202F gc=Zs columns=1 print=1 graph=0 NARROW NO-BREAK SPACE
U+002060 gc=Cf columns=0 print=1 graph=1 WORD JOINER
U+002061 gc=Cf columns=0 print=1 graph=1 FUNCTION APPLICATION
U+002062 gc=Cf columns=0 print=1 graph=1 INVISIBLE TIMES
U+002064 gc=Cf columns=0 print=1 graph=1 INVISIBLE PLUS
U+002EC1 gc=So columns=2 print=1 graph=1 CJK RADICAL TIGER
U+002F0B gc=So columns=2 print=1 graph=1 KANGXI RADICAL EIGHT
U+003000 gc=Zs columns=2 print=1 graph=0 IDEOGRAPHIC SPACE
U+003008 gc=Ps columns=2 print=1 graph=1 LEFT ANGLE BRACKET
U+00300A gc=Ps columns=2 print=1 graph=1 LEFT DOUBLE ANGLE BRACKET
U+00300C gc=Ps columns=2 print=1 graph=1 LEFT CORNER BRACKET
U+00302B gc=Mn columns=0 print=1 graph=1 IDEOGRAPHIC RISING TONE MARK
U+003030 gc=Pd columns=2 print=1 graph=1 WAVY DASH
U+003037 gc=So columns=2 print=1 graph=1 IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL
U+003041 gc=Lo columns=2 print=1 graph=1 HIRAGANA LETTER SMALL A
U+00E000 gc=Co columns=1 print=1 graph=1 <unnamed codepoint in blk=Private_Use_Area>
U+00F8FF gc=Co columns=1 print=1 graph=1 <unnamed codepoint in blk=Private_Use_Area>
U+00FB1E gc=Mn columns=0 print=1 graph=1 HEBREW POINT JUDEO-SPANISH VARIKA
U+00FE00 gc=Mn columns=0 print=1 graph=1 VARIATION SELECTOR-1
U+00FE23 gc=Mn columns=0 print=1 graph=1 COMBINING DOUBLE TILDE RIGHT HALF
U+00FE58 gc=Pd columns=2 print=1 graph=1 SMALL EM DASH
U+00FE77 gc=Lo columns=1 print=1 graph=1 ARABIC FATHA MEDIAL FORM
U+00FEFF gc=Cf columns=0 print=1 graph=1 ZERO WIDTH NO-BREAK SPACE
U+00FF06 gc=Po columns=2 print=1 graph=1 FULLWIDTH AMPERSAND
U+00FFFA gc=Cf columns=0 print=1 graph=1 INTERLINEAR ANNOTATION SEPARATOR
U+00FFFD gc=So columns=1 print=1 graph=1 REPLACEMENT CHARACTER
U+01B000 gc=Lo columns=2 print=1 graph=1 KATAKANA LETTER ARCHAIC E
U+01D165 gc=Mc columns=1 print=1 graph=1 MUSICAL SYMBOL COMBINING STEM
U+01D167 gc=Mn columns=0 print=1 graph=1 MUSICAL SYMBOL COMBINING TREMOLO-1
U+100002 gc=Co columns=1 print=1 graph=1 <unnamed codepoint in blk=Supplementary_Private_Use_Area-B>
其中一些对于它们打印什么,甚至是否打印是非常有条件的。例如,你觉得 U+F8FF 的‹›是什么样的?
然后你必须决定如何处理制表符和退格键。
另外,您将不得不考虑\p{Grapheme_Extend}
用于构建 Unicode 扩展字素簇的各种代码点;也就是说,一个用户可见的字符。并非所有这些都是非间距标记。事实上,有些根本不是标记,而是字母!有些根本不是可打印的字符,但它们改变了\p{Grapheme_Base}
它们不可避免地附加到的可打印字符;仅以变体选择器为例。
警告
这将我们带到了一个非常重要的点,它经常被潜在的 Java 程序员忘记,即使没有完全忘记,通常也被低估了。
永远、永远、永远记住Java 字符不是 Unicode 字符! Unicode 字符有两种合理的定义,Java 两者都没有。以下是两个合理的定义:
- 如果一个字符是程序员可见意义上的字符,那么一个字符就是一个 Unicode 代码点。
.
例如,无论您使用 Sun 的还是 ICU 的,这都是正则表达式引擎中的匹配项。
- 如果一个字符是用户可见意义上的字符,那么一个字符就是一个 Unicode 扩展字素簇。这是
\X
(ICU 不是 Sun)正则表达式引擎中的匹配项。
Java 所谓的“字符”是实际 Unicode 代码点的可变宽度 UTF-16 表示的低级、中断抽象的 2 字节元素。它既不是抽象代码点,也不是抽象字素。它不是抽象的东西。 Javachar
违反了抽象的信封。
是的,一些 Java 类为您提供了一个codePointAt
接口,您绝对应该使用那些可用的接口。但在许多方面,这里需要花很长时间来解释,Java 从根本上破坏了它的字符抽象——因为它没有字符抽象。
这使得在 Java 中使用 Unicode 字符和字符串最容易出错,而且通常几乎是不可能的。
祝你好运。