我想分析 char 数组中的全角或半角字符。
\n\n例如:
\n\nchar[]密码={'t','e','s','t','\xe6\x80\x9d','\xe9\xa1\x8c'};
\n\n这个char数组中有全角和半角字符。
\n\n半宽 = t,e,s,t
\n\n全宽 = \xe6\x80\x9d,\xe9\xa1\x8c
\n\n那么,如何在java中分析char数组的全角或半角呢?
\n\n多谢!
\n东亚字符的宽度在Unicode 标准的附件 #11中进行了描述,该标准讨论了East_Asian_Width
Unicode 字符的属性。
虽然,我找不到使用标准 Java 8 库查询此属性的方法,但可以使用ICU4J 库(com.ibm.icu.icu4j)来获取此值。
\n\n例如,以下代码返回UCharacter.EastAsianWidth.WIDE
:
int esw = UCharacter.getIntPropertyValue(\'\xe3\x81\x82\', UProperty.EAST_ASIAN_WIDTH);\n
Run Code Online (Sandbox Code Playgroud)\n\n对日语字符的一些测试表明,所有单字节 Shift JIS假名字符(例如半角\xef\xbd\xb6
)都被指定HALFWIDTH
,而它们的全角对应字符(例如\xe3\x82\xab
)也被指定FULLWIDTH
。所有其他全角字符(例如\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81\x88\xe3\x81\x8a
return )WIDE
和非全角字符(例如纯Abc
return )NARROW
。
该值AMBIGUOUS
需要额外小心,因为它的宽度会根据上下文而变化。例如,vim编辑器有一个ambiwidth
选项可以让用户选择是否应将其视为窄的或宽的,因为渲染取决于终端。
上述附件规定了不明确的字符:不明确的字符在东亚传统字符集中作为宽字符出现,但在非东亚使用中作为窄(即正常宽度)字符出现。
\n\n它还指出NEUTRAL
:,谈论中性字符的窄和宽是没有意义的,但因为出于所有实际目的,它们的行为类似于 Na,所以根据下面的建议,它们被视为窄字符(与 Na 相同)。
然而,我发现窄的情况并不NEUTRAL
总是如此,因为某些字符在我尝试过的编辑器中可能会显示得很宽。此外,\xe2\x85\xb6
, \xe2\x85\xb7
, \xe2\x85\xb8
, \xe2\x85\xb9
are AMBIGUOUS
,而前面的字符\xe2\x85\xba
和\xe2\x85\xbb
是NEUTRAL
,这似乎没有意义。也许未映射的字符会icu4j
回退到NEUTRAL
.
最后,UCharacter.EastAsianWidth.COUNT
只是一个常量,表示 下定义的属性数量,并且不会返回UCharacter.EastAsianWidth
任何值。getIntPropertyValue()
JDK 包含一个提到全角/半角的类:InputSubset
http://docs.oracle.com/javase/7/docs/api/java/awt/im/InputSubset.html
不幸的是,没有方法可以检查哪个字符属于哪个子集。
尽管如此,显然全角/半角对于 unicode 来说是一个明确定义的概念。互联网上可能有准确的规格。
http://en.wikipedia.org/wiki/Halfwidth_and_fullwidth_forms
http://en.wikipedia.org/wiki/DBCS
我想对于您的用例来说,0x00-0xFF 字符是半角就足够了;除unicode块“Halfwidth and Fullwidth Forms”中的半角字符外,其他字符都是全角的
boolean isHalfWidth(char c)
{
return '\u0000' <= c && c <= '\u00FF'
|| '\uFF61' <= c && c <= '\uFFDC'
|| '\uFFE8' <= c && c <= '\uFFEE' ;
}
Run Code Online (Sandbox Code Playgroud)