在java中只拆分中文字符

时间:2009-11-04 18:27:58

标签: java regex split

我正在编写一个java应用程序;但坚持这一点。

基本上我有一串汉字,还有一些可能的拉丁字符或数字,让我们说:

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

我想将除拉丁语之外的中文字符或上面的数字分为“BOT”。所以,最后我会有这样的清单:

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

如何解决此问题(对于java)?

3 个答案:

答案 0 :(得分:10)

中文字符位于某些Unicode范围内:

  • 2F00-2FDF:康熙
  • 4E00-9FAF:CJK
  • 3400-4DBF:CJK Extension

所以你基本上需要做的就是检查角色的代码点是否在已知范围内。这个例子是编写基于堆栈的解析器/拆分器的一个很好的起点,你只需要将它扩展为拉丁字母的单独数字,这应该足够明显(提示: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");
    }
}
祝你好运。

答案 1 :(得分:1)

这是我要采取的一种方法。

您可以使用Character.codePointAt(char [] charArray,int index)返回char数组中char的Unicode值。

您还需要拉丁语Unicode字符的映射。

如果查看Character.UnicodeBlock的源代码,则完整的LATIN块是区间[0x0000,0x0249]。所以基本上你检查你的Unicode代码点是否在那段时间内。

我怀疑有一种方法可以使用Character.Subset来检查它是否包含你的char,但是我还没有考虑过。

答案 2 :(得分:1)

Diclaimer:我是一个完整的Lucene新手。

使用最新版本的Lucene(撰写本文时为3.6.0),我设法接近您所需的结果。

  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.
  }

我得到的结果是:

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