Java實現(xiàn)獲取一段文字中文字符數(shù)量的工具類
1. 項目背景詳細介紹
隨著互聯(lián)網(wǎng)時代的到來,各類應用中對于文本的處理日益頻繁,其中往往需要對不同語言的字符進行分析與統(tǒng)計。在多語言混排的文本中,中文字符、英文字符、數(shù)字、標點符號等并存,而許多業(yè)務場景需要單獨統(tǒng)計中文字符的數(shù)量。典型場景包括:
- 內(nèi)容質(zhì)量檢測:在新聞、論壇、博客等編輯系統(tǒng)中,限制或提示中文字符數(shù),以保證文章長度和可讀性。
- 短信計費:國內(nèi)短信按中文與英文字符分段計費,需精確統(tǒng)計其中的中文字符數(shù)量。
- 排版排查:在排版生成時,統(tǒng)計中文字符占比,以決定字體大小、行間距、版式分割點等。
- 數(shù)據(jù)分析:在大數(shù)據(jù)文本分析中,需區(qū)分中英文數(shù)據(jù)分布,評估中文信息量等。
因此,本項目旨在設計并實現(xiàn)一個通用的 Java 工具類,能夠高效、準確地統(tǒng)計一段文本中 中文字符 的數(shù)量。工具類應兼容各類 Java 環(huán)境,接口簡單易用,并提供豐富的單元測試與文檔說明,方便集成到各種 Java 應用中。
2. 項目需求詳細介紹
為確保工具類功能完整、健壯易用,需明確以下 功能需求 與 非功能需求。
2.1 功能需求
中文字符統(tǒng)計
- 接口方法
int countChinese(String text):統(tǒng)計輸入字符串text中的中文字符個數(shù); - 要求僅統(tǒng)計 Unicode 范圍內(nèi)的漢字字符,不含標點、符號、日文漢字;
支持批量處理
- 支持對包含大量文本(如幾萬字或幾百萬字)的統(tǒng)計,要求性能盡可能高;
- 可在多線程場景下并發(fā)調(diào)用,無狀態(tài)或線程安全;
可擴展正則
- 默認使用正則
[\u4E00-\u9FFF],兼容常用漢字; - 支持可選參數(shù)自定義需要統(tǒng)計的 Unicode 區(qū)間或正則;
空值與異常處理
- 當
text為null或空字符串時,返回0; - 對非法正則或參數(shù),應拋出
IllegalArgumentException;
2.2 非功能需求
接口設計
- 提供靜態(tài)工具方法
ChineseCounter.countChinese(text); - 提供面向?qū)嵗目膳渲冒?
new ChineseCounter(pattern).count(text);
性能
- 對于大文本,應避免重復編譯正則,可復用
Pattern; - 支持流式處理(如
Reader輸入),減少內(nèi)存占用;
線程安全
- 靜態(tài)方法內(nèi)部使用線程安全的數(shù)據(jù)結構或局部變量;
- 可在多線程環(huán)境中安全調(diào)用,無需外部同步;
測試覆蓋
使用 JUnit 編寫單元測試,覆蓋正常和邊界場景:中英混排、Emoji、全空、全中文、大文本等;
文檔與注釋
- 按照 Javadoc 規(guī)范編寫類注釋、方法注釋與參數(shù)/異常說明;
- 提供使用示例和常見問題解答說明。
3. 相關技術詳細介紹
實現(xiàn)上述功能,需要掌握或了解以下 Java 核心技術點:
3.1 正則表達式(java.util.regex)
Pattern 與 Matcher
Pattern.compile(regex):將正則編譯為模式對象;Matcher matcher = pattern.matcher(text):對目標文本進行匹配;matcher.find()與matcher.group():定位并提取匹配子串;
Unicode 區(qū)間
- 常用漢字范圍:
\u4E00-\u9FFF; - 擴展?jié)h字:
\u3400-\u4DBF(CJK 擴展 A 區(qū))、\u20000-\u2A6DF(擴展 B 區(qū),需要 Surrogate Pair); - 配合正則后綴
+或{n}控制匹配;
3.2 字符與碼點
char 與 int codePoint
- Java
char為 UTF-16 單元,BMP 區(qū)漢字可直接用char匹配; - 對于擴展字符(如擴展 B 區(qū)),需要使用
text.codePoints()流式處理;
流式 API(Java 8+)
text.chars()或text.codePoints()可以逐個讀取字符/碼點;- 結合
filter與count,可實現(xiàn)函數(shù)式統(tǒng)計。
3.3 IO 與大文本處理
Reader 與 BufferedReader
對于大文本,可支持 count(Reader),逐行或逐塊讀取并統(tǒng)計,降低內(nèi)存壓力;
并發(fā)與分段統(tǒng)計
可將大文本分為多段,在多個線程中并發(fā)處理,最后匯總結果;
3.4 單元測試
JUnit 5
- 使用
@Test注解編寫用例; - 使用
@ParameterizedTest和@ValueSource提供多場景; - 驗證正確性與異常拋出。
4. 實現(xiàn)思路詳細介紹
根據(jù)需求與技術選型,設定以下設計思路:
1.工具類與實例類分離
public final class ChineseCounter:
- 私有構造方法,防止實例化;
- 公共靜態(tài)方法使用默認正則;
public class ChineseCounter.Instance:
接受自定義正則或 Unicode 區(qū)間;
內(nèi)部持有 Pattern 實例,復用匹配;
2.靜態(tài)方法實現(xiàn)
public static int countChinese(String text) {
if (text == null || text.isEmpty()) return 0;
Matcher m = DEFAULT_PATTERN.matcher(text);
int count = 0;
while (m.find()) count++;
return count;
}
流式方法實現(xiàn)
public static long countByCodePoint(String text) {
if (text == null) return 0;
return text.codePoints()
.filter(cp -> cp >= 0x4E00 && cp <= 0x9FFF)
.count();
}
Reader 版本
public static int countChinese(Reader reader) {
BufferedReader br = new BufferedReader(reader);
String line;
int total = 0;
while ((line = br.readLine()) != null) {
total += countChinese(line);
}
return total;
}
5. 完整實現(xiàn)代碼
// 文件:ChineseCounter.java
package com.example.textcounter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 中文字符統(tǒng)計工具類
* 支持靜態(tài)方法與可配置實例對象兩種方式
*/
public final class ChineseCounter {
// 默認匹配漢字的正則:包含常用漢字(CJK Unified Ideographs)
private static final Pattern DEFAULT_PATTERN = Pattern.compile("[\\u4E00-\\u9FFF]");
// 私有構造,禁止實例化
private ChineseCounter() {}
/**
* 靜態(tài)方法:統(tǒng)計字符串中的中文字符數(shù)量(使用默認范圍)
* @param text 輸入文本
* @return 中文字符個數(shù)
*/
public static int countChinese(String text) {
if (text == null || text.isEmpty()) return 0;
Matcher matcher = DEFAULT_PATTERN.matcher(text);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
/**
* 靜態(tài)方法:基于字符碼點方式統(tǒng)計中文數(shù)量(推薦:性能更優(yōu))
* @param text 輸入文本
* @return 中文字符個數(shù)
*/
public static long countChineseByCodePoint(String text) {
if (text == null) return 0;
return text.codePoints()
.filter(cp -> (cp >= 0x4E00 && cp <= 0x9FFF)) // 可擴展至其他 Unicode 區(qū)
.count();
}
/**
* 靜態(tài)方法:按行讀取字符流并統(tǒng)計中文數(shù)量(適合大文本)
* @param reader 字符流 Reader
* @return 中文字符個數(shù)
* @throws IOException 讀取異常
*/
public static int countChinese(Reader reader) throws IOException {
if (reader == null) return 0;
BufferedReader br = new BufferedReader(reader);
String line;
int total = 0;
while ((line = br.readLine()) != null) {
total += countChinese(line);
}
return total;
}
/**
* 可配置實例類(支持自定義正則)
*/
public static class Instance {
private final Pattern pattern;
/**
* 使用正則表達式創(chuàng)建統(tǒng)計實例
* @param regex 自定義正則(必須非空)
*/
public Instance(String regex) {
if (regex == null || regex.isEmpty()) {
throw new IllegalArgumentException("正則表達式不能為空");
}
this.pattern = Pattern.compile(regex);
}
/**
* 使用 Unicode 范圍創(chuàng)建統(tǒng)計實例
* @param start 起始碼點(如 0x4E00)
* @param end 結束碼點(如 0x9FFF)
*/
public Instance(int start, int end) {
if (start > end) {
throw new IllegalArgumentException("起始碼點不能大于結束碼點");
}
String regex = String.format("[%s-%s]",
new String(Character.toChars(start)),
new String(Character.toChars(end)));
this.pattern = Pattern.compile(regex);
}
/**
* 使用該實例統(tǒng)計字符串中的匹配字符數(shù)量
* @param text 輸入文本
* @return 匹配字符數(shù)量
*/
public int count(String text) {
if (text == null || text.isEmpty()) return 0;
Matcher matcher = pattern.matcher(text);
int count = 0;
while (matcher.find()) {
count++;
}
return count;
}
}
}
// 文件:ChineseCounterTest.java
package com.example.textcounter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* 中文字符統(tǒng)計測試類
*/
public class ChineseCounterTest {
@Test
public void testNullAndEmpty() {
assertEquals(0, ChineseCounter.countChinese(null));
assertEquals(0, ChineseCounter.countChinese(""));
}
@Test
public void testMixedContent() {
String text = "你好,world!123";
assertEquals(2, ChineseCounter.countChinese(text));
}
@Test
public void testOnlyChinese() {
String text = "這是純中文";
assertEquals(5, ChineseCounter.countChinese(text));
}
@Test
public void testCodePointMethod() {
String text = "ABC和中文組合??";
assertEquals(3, ChineseCounter.countChineseByCodePoint(text));
}
@Test
public void testCustomInstanceRegex() {
ChineseCounter.Instance custom = new ChineseCounter.Instance("[\\u4E00-\\u9FFF]");
assertEquals(4, custom.count("中英文混排測試"));
}
@Test
public void testUnicodeRange() {
ChineseCounter.Instance range = new ChineseCounter.Instance(0x4E00, 0x9FFF);
assertEquals(2, range.count("Hello中國"));
}
@Test
public void testInvalidRegex() {
assertThrows(IllegalArgumentException.class, () -> new ChineseCounter.Instance(""));
}
@Test
public void testInvalidUnicodeRange() {
assertThrows(IllegalArgumentException.class, () -> new ChineseCounter.Instance(0x9FFF, 0x4E00));
}
}
6. 代碼詳細解讀(方法作用說明)
countChinese(String text):使用正則[\\u4E00-\\u9FFF]統(tǒng)計字符串中中文字符數(shù)量;countChineseByCodePoint(String text):使用 Unicode 碼點判斷是否屬于常用漢字區(qū)間,提高性能;countChinese(Reader reader):適用于大文本,按行讀取字符流并統(tǒng)計;ChineseCounter.Instance(String regex):允許用戶自定義正則表達式作為匹配規(guī)則;ChineseCounter.Instance(int start, int end):允許用戶以 Unicode 范圍構造匹配規(guī)則;count(String text)(實例方法):對輸入文本應用實例配置的規(guī)則進行統(tǒng)計;- 測試類
ChineseCounterTest:使用 JUnit 驗證工具類對各種文本場景的處理是否正確。
7. 項目詳細總結
本項目實現(xiàn)了一個輕量級、高性能、可復用的中文字符統(tǒng)計工具。它通過 Java 正則表達式、字符碼點等核心技術,準確識別一段文字中的常用中文字符數(shù)量,并提供了靈活的 API 接口:
- 靜態(tài)方法簡單易用,滿足大多數(shù)場景;
- 實例方法可擴展性強,支持定制匹配范圍;
- 支持大文本與字符流處理,避免內(nèi)存問題;
- 完整的單元測試覆蓋,確保準確性與穩(wěn)定性;
- 零依賴,適用于所有 Java 應用(桌面、后端、移動)。
本工具可廣泛應用于文本分析、內(nèi)容審核、界面字符計數(shù)等需求場景中,也可作為其他 NLP 工具的子模塊進行集成。
8. 項目常見問題及解答
Q1: 為什么正則只用了 [\\u4E00-\\u9FFF]?
這是最常用的 CJK 漢字區(qū),基本能覆蓋日常中文應用。若需要擴展到 CJK 擴展 A/B/C 區(qū),可在 countChineseByCodePoint() 中修改范圍。
Q2: 是否支持統(tǒng)計標點符號、日文、韓文?
默認不支持。如果需要,可通過實例化構造器傳入包含這些字符的正則(如 [\u4E00-\u9FFF\u3000-\u303F])。
Q3: 對 emoji 有影響嗎?
沒有影響,emoji 屬于 Unicode 較高區(qū)段,不會被默認正則匹配。
Q4: 處理超大文本安全嗎?
是。通過 Reader 輸入并逐行處理的版本可以用于幾 MB 甚至 GB 級別的文本處理。
Q5: 線程安全嗎?
工具類無狀態(tài);實例類僅讀共享 Pattern,是線程安全的;可放心在并發(fā)環(huán)境中使用。
9. 擴展方向與性能優(yōu)化
1.多 Unicode 范圍支持
- 擴展匹配范圍至 CJK 擴展 A(0x3400-0x4DBF)、擴展 B(0x20000-0x2A6DF)等;
- 支持中文標點(0x3000-0x303F)等。
2.字符頻率統(tǒng)計
- 返回 Map<Character, Integer> 統(tǒng)計中文字符的使用頻率;
- 用于詞云生成、關鍵字提取等。
3.多線程加速
將長文本切片后在并行流中統(tǒng)計,進一步提升性能;
4.使用 Re2J 替代 JDK 正則引擎
對正則匹配密集場景可提高性能;
5.集成語言識別與 NLP 模塊
搭配 HanLP、Jieba 分詞庫進一步識別實體、語法等。
到此這篇關于Java實現(xiàn)獲取一段文字中文字符數(shù)量的工具類的文章就介紹到這了,更多相關Java獲取文字中文字符數(shù)量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java8 Supplier接口和Consumer接口原理解析
這篇文章主要介紹了Java8 Supplier接口和Consumer接口原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-04-04
基于UDP協(xié)議實現(xiàn)聊天系統(tǒng)
這篇文章主要為大家詳細介紹了基于UDP協(xié)議實現(xiàn)聊天系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-04-04
IDEA利用jclasslib 修改class文件的實現(xiàn)
這篇文章主要介紹了IDEA利用jclasslib 修改class文件的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-02-02
Mybatis-Plus實現(xiàn)用戶ID自增出現(xiàn)的問題解決
項目基于 SpringBoot + MybatisPlus 3.5.2 使用數(shù)據(jù)庫自增ID時, 出現(xiàn)重復鍵的問題,本文就來介紹一下解決方法,感興趣的可以了解一下2023-09-09
BeanUtils.copyProperties()所有的空值不復制問題
這篇文章主要介紹了BeanUtils.copyProperties()所有的空值不復制問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06
Spring?Boot集成Redisson實現(xiàn)延遲隊列
本文詳細介紹了電商支付場景中利用Redisson的RDelayedQueue實現(xiàn)訂單的延遲關閉功能,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-08-08

