2009-11-04 21 views
7

Sto scrivendo un'applicazione java; ma bloccato su questo punto.Per dividere solo caratteri cinesi in java

Fondamentalmente ho una stringa di caratteri cinesi con anche alcune possibili caratteri latini o numeri, consente di dire:

查詢促進民間參與公共建設法(210BOT法). 

voglio dividere quei caratteri cinesi, tranne il latino o numeri come "BOT" di cui sopra. Così, alla fine avrò questo tipo di lista:

[ 查, 詢, 促, 進, 民, 間, 參, 與, 公, 共, 建, 設, 法, (, 210, BOT, 法, ), ., ]

Come posso risolvere questo problema (per Java)?

risposta

10

caratteri cinesi si trova entro un certo Unicode gamme:

  • 2F00-2FDF: Kangxi
  • 4E00-9FAF: CJK
  • 3400-4DBF: CJK estensione

Quindi tutto quello che in pratica è necessario verificare se il codice del personaggio si trova all'interno degli intervalli noti. Questo esempio è un buon punto di partenza per scrivere un parser stackbased/splitter, avete solo bisogno di estenderlo per separare le cifre da lettere latine, che dovrebbe essere abbastanza ovvio (suggerimento: Character#isDigit()):

Set<UnicodeBlock> chineseUnicodeBlocks = new HashSet<UnicodeBlock>() {{ 
    add(UnicodeBlock.CJK_COMPATIBILITY); 
    add(UnicodeBlock.CJK_COMPATIBILITY_FORMS); 
    add(UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS); 
    add(UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT); 
    add(UnicodeBlock.CJK_RADICALS_SUPPLEMENT); 
    add(UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A); 
    add(UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B); 
    add(UnicodeBlock.KANGXI_RADICALS); 
    add(UnicodeBlock.IDEOGRAPHIC_DESCRIPTION_CHARACTERS); 
}}; 

String mixedChinese = "查詢促進民間參與公共建設法(210BOT法)"; 

for (char c : mixedChinese.toCharArray()) { 
    if (chineseUnicodeBlocks.contains(UnicodeBlock.of(c))) { 
     System.out.println(c + " is chinese"); 
    } else { 
     System.out.println(c + " is not chinese"); 
    } 
} 

Buona fortuna.

+0

Come estensione, credo che una classe di caratteri in un regexp. anche gli intervalli sopra citati in Unicode funzionerebbero. –

+0

Non proprio se si vuole intercettare anche su gruppi di cifre/lettere/trattini/indipendentemente. Un parser stackbased è uno strumento migliore per questo tipo di lavoro. – BalusC

+0

Funziona anche per giapponese e coreano? –

1

Ecco un approccio che vorrei adottare.

È possibile utilizzare Character.codePointAt (char [] charArray, int index) per restituire il valore Unicode per un carattere nel proprio array di caratteri.

Avrete anche bisogno di una mappatura di caratteri latini Unicode.

Se si cerca nell'origine di Character.UnicodeBlock, il blocco LATIN completo è l'intervallo [0x0000, 0x0249]. Quindi in pratica si controlla se il proprio punto di codice Unicode è da qualche parte all'interno di tale intervallo.

Ho il sospetto che ci sia un modo per usare solo un carattere.Subset per controllare se contiene il tuo carattere, ma non l'ho esaminato.

1

Diclaimer: Sono un principiante completo di Lucene.

Utilizzando l'ultima versione di Lucene (3.6.0 al momento della scrittura) riesco ad avvicinarmi al risultato richiesto.

Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_36, Collections.emptySet()); 

    List<String> words = new ArrayList<String>(); 
    TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(original)); 
    CharTermAttribute termAttribute = tokenStream.addAttribute(CharTermAttribute.class); 

    try { 
    tokenStream.reset(); // Resets this stream to the beginning. (Required) 
    while (tokenStream.incrementToken()) { 
     words.add(termAttribute.toString()); 
    } 
    tokenStream.end(); // Perform end-of-stream operations, e.g. set the final offset. 
    } 
    finally { 
    tokenStream.close(); // Release resources associated with this stream. 
    } 

Il risultato che ottengo è:

[查, 詢, 促, 進, 民, 間, 參, 與, 公, 共, 建, 設, 法, 210bot, 法] 
Problemi correlati