gpt4 book ai didi

java - 如何在Java中获取字符类型的类别名称?

转载 作者:行者123 更新时间:2023-12-04 13:13:26 26 4
gpt4 key购买 nike

Character.getType(int codePoint)返回一个整数,我找不到方法
从中获取 unicode 类别名称,例如“Lu”或“Cn”。
我想要的是一种方法,例如Character.getCategoryTypeName(int codePoint)返回一个表示类型的字符串。

类别名称在常量注释中,并且
一种方法是为返回的类型编写一个 switch case,然后手动编码类型名称,如下所示:

我原来的计划是这样的:

for (int i = 0; i <= 0x10FFFF; i++) {
switch (Character.getType(i)) {

// General category "Sc" in the Unicode specification.
// public static final byte CURRENCY_SYMBOL = 26;
case Character.CURRENCY_SYMBOL:
map.put(i, "Sc");
break;

....
}
}

然而这将是非常乏味的。是否有自动方式或库来完成任务?

最佳答案

正如评论的那样,目前似乎没有与 Java 捆绑的此类功能。如 Marcono1234 commented , a feature-request is on the books但尚未实现。
自我注意:如果我用 Brian Goetz 擦手肘或 Mark Reinhold在 session 上,要求/恳求/恳求他们对与 code points 的合作进行重大改进和 Unicode在 java 。
我想出了几种方法来为 Unicode 定义的 30 个“一般类别”项目中的每一个生成所需的两个字母的名称。 (这个由两个字母组成的名字在 Unicode 规范中被称为“别名”。)我的一个实现只是一个 switch为每个别名进行硬编码。另一个更复杂,定义了几个枚举。
这两个实现都是我创建的,只是作为练习。我没有在生产中使用它们。我并不是说它们是最好的路线,但希望它们可能被证明是有用的,或者至少能激发其他人做出更好的努力。
基本的
在 Java 14+ 中,使用 switch Character 上定义的每个“一般类别”常量的表达式类(class)。如果不熟悉,请参阅 JEP 361: Switch Expressions .

public String unicodeGeneralCategoryAliasForCodePoint ( int codePoint ) {
return switch ( Character.getType( codePoint ) ) {

// L, Letter
case Character.UPPERCASE_LETTER -> "Lu";
case Character.LOWERCASE_LETTER -> "Ll";
case Character.TITLECASE_LETTER -> "Lt";
case Character.MODIFIER_LETTER -> "Lm";
case Character.OTHER_LETTER -> "Lo";

// M, Mark
case Character.NON_SPACING_MARK -> "Mn";
case Character.COMBINING_SPACING_MARK -> "Mc";
case Character.ENCLOSING_MARK -> "Me";

// N, Number
case Character.DECIMAL_DIGIT_NUMBER -> "Nd";
case Character.LETTER_NUMBER -> "Nl";
case Character.OTHER_NUMBER -> "No";

// P, Punctuation
case Character.CONNECTOR_PUNCTUATION -> "Pc";
case Character.DASH_PUNCTUATION -> "Pd";
case Character.START_PUNCTUATION -> "Ps";
case Character.END_PUNCTUATION -> "Pe";
case Character.INITIAL_QUOTE_PUNCTUATION -> "Pi";
case Character.FINAL_QUOTE_PUNCTUATION -> "Pf";
case Character.OTHER_PUNCTUATION -> "Po";

// S, Symbol
case Character.MATH_SYMBOL -> "Sm";
case Character.CURRENCY_SYMBOL -> "Sc";
case Character.MODIFIER_SYMBOL -> "Sk";
case Character.OTHER_SYMBOL -> "So";

// Z, Separator
case Character.SPACE_SEPARATOR -> "Zs";
case Character.LINE_SEPARATOR -> "Zl";
case Character.PARAGRAPH_SEPARATOR -> "Zp";

// C, Other
case Character.CONTROL -> "Cc";
case Character.FORMAT -> "Cf";
case Character.SURROGATE -> "Cs";
case Character.PRIVATE_USE -> "Co";
case Character.UNASSIGNED -> "Cn";

default -> "ERROR - Unexpected General Category type for code point " + codePoint + ". Message # 5d44e5fd-d60e-4b02-9431-ad57c56657f5.";
};
}
用法:
String alias = x.unicodeGeneralCategoryAliasForCodePoint( 65 );

Lu


豪华房
在这种替代方法中,我定义了一对枚举:
  • UnicodeGeneralCategory 30 个对象,一个用于定义在 section 4.5 of the Unicode 13 spec 的第 170-172 页上的每个一般类别项目.这些项目列于 this Wikipedia page .
  • UnicodeMajorClassUnicodeGeneralCategory 的对象进行分组分成 Unicode 规范定义的组:字母、标记、数字、标点符号、符号、分隔符和其他。最后一个“其他”值得注意,因为它涵盖了不可打印的“控制”字符以及未分配给任何字符的绝大多数代码点。当looping over all the possible code points ,我们想跳过这些。
  • UnicodeGeneralCategory 中我的枚举对象的名称从 Character 上声明的常量子集复制描述以短语“一般类别”开头的类。这些常量名称与官方的 Unicode 名称有些不同,但足够接近。我按照 Unicode 规范中列出的相同顺序定义了这些。
    package work.basil.unicode.category;

    import java.util.Arrays;
    import java.util.Optional;

    // For more info about Unicode General Category, see section 4.5 of the Unicode 13.0 spec, pages 170-172.
    // https://www.unicode.org/versions/Unicode13.0.0/ch04.pdf
    public enum UnicodeGeneralCategory {

    // See Wikipedia page list the General Category values defined in Unicode 13.
    // L, Letter
    UPPERCASE_LETTER( Character.UPPERCASE_LETTER , "Lu" , "Letter" , "uppercase" ),
    LOWERCASE_LETTER( Character.LOWERCASE_LETTER , "Ll" , "Letter" , "lowercase" ),
    TITLECASE_LETTER( Character.TITLECASE_LETTER , "Lt" , "Letter" , "titlecase" ),
    MODIFIER_LETTER( Character.MODIFIER_LETTER , "Lm" , "Letter" , "modifier" ),
    OTHER_LETTER( Character.OTHER_LETTER , "Lo" , "Letter" , "other" ),

    // M, Mark
    NON_SPACING_MARK( Character.NON_SPACING_MARK , "Mn" , "Mark" , "nonspacing" ),
    COMBINING_SPACING_MARK( Character.COMBINING_SPACING_MARK , "Mc" , "Mark" , "spacing combining" ),
    ENCLOSING_MARK( Character.ENCLOSING_MARK , "Me" , "Mark" , "enclosing" ),

    // N, Number
    DECIMAL_DIGIT_NUMBER( Character.DECIMAL_DIGIT_NUMBER , "Nd" , "Number" , "decimal digit" ),
    LETTER_NUMBER( Character.LETTER_NUMBER , "Nl" , "Number" , "letter" ),
    OTHER_NUMBER( Character.OTHER_NUMBER , "No" , "Number" , "other" ),

    // P, Punctuation
    CONNECTOR_PUNCTUATION( Character.CONNECTOR_PUNCTUATION , "Pc" , "Punctuation" , "connector" ),
    DASH_PUNCTUATION( Character.DASH_PUNCTUATION , "Pd" , "Punctuation" , "dash" ),
    START_PUNCTUATION( Character.START_PUNCTUATION , "Ps" , "Punctuation" , "open" ),
    END_PUNCTUATION( Character.END_PUNCTUATION , "Pe" , "Punctuation" , "close" ),
    INITIAL_QUOTE_PUNCTUATION( Character.INITIAL_QUOTE_PUNCTUATION , "Pi" , "Punctuation" , "initial quote" ),
    FINAL_QUOTE_PUNCTUATION( Character.FINAL_QUOTE_PUNCTUATION , "Pf" , "Puntuation" , "final quote" ),
    OTHER_PUNCTUATION( Character.OTHER_PUNCTUATION , "Po" , "Punctuation" , "other" ),

    // S, Symbol
    MATH_SYMBOL( Character.MATH_SYMBOL , "Sm" , "Symbol" , "math" ),
    CURRENCY_SYMBOL( Character.CURRENCY_SYMBOL , "Sc" , "Symbol" , "currency" ),
    MODIFIER_SYMBOL( Character.MODIFIER_SYMBOL , "Sk" , "Symbol" , "modifier" ),
    OTHER_SYMBOL( Character.OTHER_SYMBOL , "So" , "Symbol" , "other" ),

    // Z, Separator
    SPACE_SEPARATOR( Character.SPACE_SEPARATOR , "Zs" , "Separator" , "space" ),
    LINE_SEPARATOR( Character.LINE_SEPARATOR , "Zl" , "Separator" , "line" ),
    PARAGRAPH_SEPARATOR( Character.PARAGRAPH_SEPARATOR , "Zp" , "Separator" , "paragraph" ),

    // C, Other
    CONTROL( Character.CONTROL , "Cc" , "Other" , "control" ),
    FORMAT( Character.FORMAT , "Cf" , "Other" , "format" ),
    SURROGATE( Character.SURROGATE , "Cs" , "Other" , "surrogate" ),
    PRIVATE_USE( Character.PRIVATE_USE , "Co" , "Other" , "private use" ),
    UNASSIGNED( Character.UNASSIGNED , "Cn" , "Other" , "not assigned" );


    // Fields.
    private byte characterClassConstantForGeneralCategory;
    private String alias, major, minor;

    // Constructor.
    UnicodeGeneralCategory ( byte characterClassConstantForGeneralCategory , String alias , String major , String minor ) {
    this.characterClassConstantForGeneralCategory = characterClassConstantForGeneralCategory;
    this.alias = alias;
    this.major = major;
    this.minor = minor;
    }

    public static UnicodeGeneralCategory forCodePoint ( int codePoint ) {
    if ( ! Character.isValidCodePoint( codePoint ) ) {
    throw new IllegalArgumentException( "Code point " + codePoint + " is invalid. Must be within 0 to U+10FFFF ( 1,114,111 ) inclusive." );
    }
    Optional < UnicodeGeneralCategory > optionalUnicodeGeneralCategory = Arrays.stream( UnicodeGeneralCategory.values() ).filter( category -> category.characterClassConstantForGeneralCategory == Character.getType( codePoint ) ).findAny();
    if ( optionalUnicodeGeneralCategory.isEmpty() ) {
    throw new IllegalStateException( "No general category defined in this enum matching `Character.getType( codePoint )`: " + Character.getType( codePoint ) );
    } else {
    return optionalUnicodeGeneralCategory.get();
    }
    }

    public static UnicodeGeneralCategory forAlias ( String abbrev ) {
    Optional < UnicodeGeneralCategory > optionalUnicodeGeneralCategory = Arrays.stream( UnicodeGeneralCategory.values() ).filter( category -> category.alias == abbrev ).findAny();
    if ( optionalUnicodeGeneralCategory.isEmpty() ) {
    throw new IllegalArgumentException( "No general category defined in this enum for abbreviation " + abbrev );
    } else {
    return optionalUnicodeGeneralCategory.get();
    }
    }

    // Getters
    public String getAlias () {
    return this.alias;
    }

    public String getMajor () {
    return this.major;
    }

    public String getMinor () {
    return this.minor;
    }

    public byte getCharacterClassConstant () {
    return this.characterClassConstantForGeneralCategory;
    }

    public String getDisplayName () {
    return this.alias + " – " + this.major + ", " + this.minor;
    }

    }

    … 和 …
    package work.basil.unicode.category;

    import java.util.EnumSet;
    import java.util.Set;

    public enum UnicodeMajorClass {
    L_Letter( "L" , "Letter" , EnumSet.of( UnicodeGeneralCategory.UPPERCASE_LETTER , UnicodeGeneralCategory.LOWERCASE_LETTER , UnicodeGeneralCategory.TITLECASE_LETTER , UnicodeGeneralCategory.MODIFIER_LETTER , UnicodeGeneralCategory.OTHER_LETTER ) ),
    M_MARK( "M" , "Mark" , EnumSet.of( UnicodeGeneralCategory.NON_SPACING_MARK , UnicodeGeneralCategory.COMBINING_SPACING_MARK , UnicodeGeneralCategory.ENCLOSING_MARK ) ),
    N_NUMBER( "N" , "Number" , EnumSet.of( UnicodeGeneralCategory.DECIMAL_DIGIT_NUMBER , UnicodeGeneralCategory.LETTER_NUMBER , UnicodeGeneralCategory.OTHER_LETTER ) ),
    P_PUNCTUATION( "P" , "Punctuation" , EnumSet.of( UnicodeGeneralCategory.CONNECTOR_PUNCTUATION , UnicodeGeneralCategory.DASH_PUNCTUATION , UnicodeGeneralCategory.START_PUNCTUATION , UnicodeGeneralCategory.END_PUNCTUATION , UnicodeGeneralCategory.INITIAL_QUOTE_PUNCTUATION , UnicodeGeneralCategory.FINAL_QUOTE_PUNCTUATION , UnicodeGeneralCategory.OTHER_PUNCTUATION ) ),
    S_SYMBOL( "S" , "Symbol" , EnumSet.of( UnicodeGeneralCategory.MATH_SYMBOL , UnicodeGeneralCategory.CURRENCY_SYMBOL , UnicodeGeneralCategory.MODIFIER_SYMBOL , UnicodeGeneralCategory.OTHER_SYMBOL ) ),
    Z_SEPARATOR( "Z" , "Separator" , EnumSet.of( UnicodeGeneralCategory.SPACE_SEPARATOR , UnicodeGeneralCategory.LINE_SEPARATOR , UnicodeGeneralCategory.PARAGRAPH_SEPARATOR ) ),
    C_OTHER( "C" , "Other" , EnumSet.of( UnicodeGeneralCategory.CONTROL , UnicodeGeneralCategory.FORMAT , UnicodeGeneralCategory.SURROGATE , UnicodeGeneralCategory.PRIVATE_USE , UnicodeGeneralCategory.UNASSIGNED ) );

    private String alias;
    private String name;
    private Set < UnicodeGeneralCategory > categories;

    UnicodeMajorClass ( String alias , String name , Set < UnicodeGeneralCategory > categories ) {
    this.alias = alias;
    this.name = name;
    this.categories = categories;
    }

    public String getAlias () {
    return alias;
    }

    public String getName () {
    return name;
    }

    public Set < UnicodeGeneralCategory > getCategories () {
    return categories;
    }

    public String getDisplayName () {
    return this.alias + " – " + this.name;
    }

    public boolean coversCodePoint ( int codePoint ) {
    return this.getCategories().contains( UnicodeGeneralCategory.forCodePoint( codePoint ) );
    }
    }
    用法:
  • UnicodeGeneralCategory.forCodePoint( yourCodePointGoesHere ).getAlias()是您在问题顶部提出的要求。
  • UnicodeMajorClass.C_OTHER.coversCodePoint( codePoint )跳过那些讨厌的不可打印/未分配的代码点。

  • 另外,获得 String对于由代码点编号表示的单个字符,请调用 Character.toString( codePoint ) .
    我们可以使用这两个枚举来报告所有代码点。
    package work.basil.text;

    import work.basil.unicode.category.UnicodeMajorClass;

    public class DumpCharacters {
    public static void main ( String[] args ) {
    System.out.println( "INFO - Demo starting. " );

    for ( int codePoint = 0 ; codePoint <= Character.MAX_CODE_POINT ; codePoint++ ) {
    if ( Character.isValidCodePoint( codePoint ) ) // If code point is valid.
    {
    if ( UnicodeMajorClass.C_OTHER.coversCodePoint( codePoint ) ) // If control character.
    {
    // No code needed. Skip over this code point as it is not a printable character.
    } else {
    System.out.println( codePoint + " code point is named: " + Character.getName( codePoint ) + " = " + Character.toString( codePoint ) );
    }
    } else {
    System.out.println( "ERROR - Invalid code point number: " + codePoint );
    }
    }

    System.out.println( "INFO - Demo ending. " );
    }
    }
    运行时:
    INFO - Demo starting. 
    32 code point is named: SPACE =
    33 code point is named: EXCLAMATION MARK = !
    34 code point is named: QUOTATION MARK = "
    35 code point is named: NUMBER SIGN = #
    36 code point is named: DOLLAR SIGN = $
    37 code point is named: PERCENT SIGN = %
    38 code point is named: AMPERSAND = &

    122 code point is named: LATIN SMALL LETTER Z = z
    123 code point is named: LEFT CURLY BRACKET = {
    124 code point is named: VERTICAL LINE = |
    125 code point is named: RIGHT CURLY BRACKET = }
    126 code point is named: TILDE = ~
    160 code point is named: NO-BREAK SPACE =  
    161 code point is named: INVERTED EXCLAMATION MARK = ¡

    917998 code point is named: VARIATION SELECTOR-255 = 󠇮
    917999 code point is named: VARIATION SELECTOR-256 = 󠇯
    INFO - Demo ending.

    关于java - 如何在Java中获取字符类型的类别名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24248369/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com