当前位置: 首页 > news >正文

生僻字处理工具类

对于生僻字的处理可以用到下面相关编码

  • 查询汉字对应的编码:https://www.qqxiuzi.cn/bianma/zifuji.php

文章目录

  • 生僻字处理
    • 概述
    • 功能介绍
    • 快速开始
      • 判断是否是生僻字
      • utf8字符串转gbk伪码
      • gb18030字符串转gbk伪码
      • gbk伪码转utf8
      • gbk伪码转gb18030

生僻字处理

概述

  • 在系统存储、跨系统报文或文件传输过程中,保证生僻字信息的完整性。

功能介绍

  • 通过生僻字工具类,判断传入的字符串中是否包含生僻字。如果包含生僻字,可以把当前字符的字符集(utf8gb18030)转换成 gbk伪码 的形式来表示,
    gbk伪码标识符以前缀为 `H【反引号+H】来区分
  • 如:生僻字(“䶮”),转成gbk伪码的形式:`H4DAE,也可以对gbk伪码进行解码操作,解码后就还原当前的字符为:“䶮”

快速开始

  • 生僻字工具类主要有如下几个方法
/*** 生僻字工具类** @author xdr630*/
public final class RareCharacterUtils {/*** 生僻字前缀*/private static final String HEX_PREFIX = "`H";private static final Charset GB18030 = Charset.forName("gb18030");private RareCharacterUtils() {}/*** 判断字符串中是否有生僻字** @param text 字符串* @return 结果*/public static boolean containsRareCharacter(String text) {for (int i = 0; i < text.length(); i++) {int c = text.codePointAt(i);if (isRareCharacter(c)) {// 发现生僻字,返回 truereturn true;}//判断是否包含伪码标识, 包含`H,且后续跟进至少两位16进制if (c == '`' && i < text.length() - 3) {int next = text.codePointAt(i + 1);if (next == 'H') {return true;}}}// 没有发现生僻字,返回 falsereturn false;}/*** 判断是否包含生僻字符.** @param c unicode代码点* @return boolean*/private static boolean isRareCharacter(int c) {// 康熙部首、基本汉字补、表情符号?、CJK EXT-B~F、CJK兼容扩展、CJK EXT-Gif ((c >= 0x2F00 && c <= 0x2FDF) || (c >= 0x9FA6 && c <= 0x9FEF) || (c >= 0x10000 && c <= 0x1FFFF) ||(c >= 0x20000 && c <= 0x2F7FF) || (c >= 0x2F800 && c <= 0x2FA1F) || (c >= 0x30000 && c <= 0x3FFFF)) {return true;}// 非生僻字if (c <= 0x7F || c == 0x00B0 || c == 0x00B1 || c == 0x00B7 || (c >= 0x3000 && c <= 0x3003) ||(c >= 0x3005 && c <= 0x3017) || (c >= 0x4E00 && c <= 0x9FA5) || (c >= 0xFF01 && c <= 0xFF5E)) {return false;}// unicode理论最大值U+10FFFFreturn c <= 0x10FFFF;}/*** 字符转gbk伪码,前缀加 `H 标识符** @param text 字符串* @return gbk伪码*/public static String utf8ToGbk(String text) {return charsetToPseudocode(StandardCharsets.UTF_8, text);}/*** 字符转gbk伪码,前缀加 `H 标识符** @param text 字符串* @return gbk伪码*/public static String gb18030ToGbk(String text) {return charsetToPseudocode(GB18030, text);}/*** gbk伪码还原成utf8** @param input gbk伪码字符串* @return utf8编码字符串*/public static String gbkToUtf8(String input) {return gbkPseudocodeToUtf8OrGb18030(input);}/*** gbk伪码还原成gb18030** @param input gbk伪码字符串* @return gb18030编码字符串*/public static String gbkToGb18030(String input) {return gbkPseudocodeToUtf8OrGb18030(input);}/*** 字符转gbk伪码,前缀加 `H 标识符.** @param charset     字符集* @param inputString 字符串* @return gbk伪码*/private static String charsetToPseudocode(Charset charset, String inputString) {if (!charset.canEncode()) {throw new IllegalArgumentException("not support charset: " + charset.name());}int cpCount = inputString.codePointCount(0, inputString.length());StringBuilder sb = new StringBuilder();for (int index = 0; index < cpCount; ++index) {// 获取当前字符的起始位置和下一个字符的位置int i = inputString.offsetByCodePoints(0, index);int nextI = inputString.offsetByCodePoints(0, index + 1);// 获取当前字符的代码点int codepoint = inputString.codePointAt(i);// 获取当前字符String str = inputString.substring(i, nextI);if (containsRareCharacter(str)) {// 如果当前字符是生僻字,转换为伪码,并加上前缀String s = Integer.toHexString(codepoint).toUpperCase();if (s.length() < 5) {// 如果unicode码小于5位,则补足5位s = "0000".substring(0, 5 - s.length()) + s;}sb.append(HEX_PREFIX).append(s);} else {sb.append(str);}}return sb.toString();}/*** gbk伪码转utf8或gb18030** @param gbkPseudocode gbk伪码字符串* @return utf8或gb18030字符串*/private static String gbkPseudocodeToUtf8OrGb18030(String gbkPseudocode) {StringBuilder sb = new StringBuilder();int length = gbkPseudocode.length();int index = 0;while (index < length) {char ch = gbkPseudocode.charAt(index);if (ch != '`') {// 非前缀字符,直接添加到结果中sb.append(ch);index++;continue;}// 如果为反引号字符就+1跳过index++;if (index >= length || gbkPseudocode.charAt(index) != 'H') {// 非生僻字前缀字符,将反引号添加到结果中sb.append('`');if (index < length) {sb.append(gbkPseudocode.charAt(index));index++;}continue;}// 前缀字符 `H` 表示生僻字index++;StringBuilder hexCode = new StringBuilder();if (index < length) {char nextCh = gbkPseudocode.charAt(index);if (Character.isLetterOrDigit(nextCh)) {// 解析生僻字的十六进制编码while (index < length && isHexCode(nextCh)) {hexCode.append(nextCh);// 继续解析下一个字符index++;if (index < length) {nextCh = gbkPseudocode.charAt(index);}// 当unicode长度达到4时,解析判断是否为生僻字if (hexCode.length() < 4) {continue;}// 解决2CC5 'ⳅ'与2CC56 '𬱖' 二义性冲突的问题,优先按5个字节逻辑处理if (hexCode.length() == 4 && index < length && isHexCode(nextCh)) {continue;}int codepoint = Integer.parseInt(hexCode.toString(), 16);if (isRareCharacter(codepoint)) {//判断伪码unicode串是否为为生僻字, 是则转成生僻字字符输出sb.append(Character.toChars(codepoint));hexCode = null;break;}}}}if (hexCode != null) {sb.append("`H").append(hexCode);}}return sb.toString();}private static boolean isHexCode(char ch) {return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');}}

判断是否是生僻字

  • 判断传入的字符串中是否包含生僻字,如果包含生僻字就返回 true,非生僻字就返回 false
public static boolean containsRareCharacter(String text)
  • 案例如下:
// 生僻字
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("䶮")); true
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("𬱖")); true
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("崔龿")); true
// 非生僻字
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("!@#$%^&*()_+-=[]{}\\|;':\",./<>?")); false
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("!@#$%^&*()_+-=[]\{}|;':",./<>?")); false
Assertions.assertTrue(RareChineseUtils.containsRareCharacter("你好")); false

utf8字符串转gbk伪码

  • 将 UTF-8 编码的字符串转换为 GBK 编码的伪码字符串,以 `H 的形式来标注生僻字的前缀
  • 传入 UTF-8 编码的字符串参数,返回 GBK 伪码字符串结果
public static String utf8ToGbk(String text) 
  • 案例如下:“𬱖” 为生僻字,转码为 `H2CC56 ,"你好 " 为非生僻字就不会转码

hexStringToBytes:将一个十六进制字符串转换为字节数组的方法,将每两个十六进制字符解析成一个字节,并将其存储在字节数组中返回。

String c1 = utf8ToGbk("张𬱖。,,.");
String c2 = utf8ToGbk("你好");
Assertions.assertEquals("张`H2CC56。,,.", c1);
Assertions.assertEquals("你好", c2);String str = new String(hexStringToBytes("E5B494E9BEBF"), StandardCharsets.UTF_8);
System.out.println(str.getBytes());
Assertions.assertEquals("崔龿", str);
Assertions.assertEquals("崔`H9FBF", utf8ToGbk(str));

gb18030字符串转gbk伪码

  • 原理和【utf8字符串转gbk伪码】类似,区别在于传入的字符集编码是 gb18030
  • 传入 gb18030 编码的字符串参数,返回 GBK 伪码字符串结果
public static String gb18030ToGbk(String text)
  • 案例如下:
String str = new String(hexStringToBytes("B4DE82359138"), GB18030);
Assertions.assertEquals("崔龿", str);
Assertions.assertEquals("崔`H9FBF", gb18030ToGbk(str));

gbk伪码转utf8

  • 将 GBK 伪码字符串还原成 UTF-8 编码的字符串
  • 生僻字转码为 `Hxxx 的形式后,通过该方法把转码后的生僻字解析为 UTF-8 编码的字符串
public static String gbkToUtf8(String input)
  • 案例如下:

bytesToHex方法是将字节数组转换为十六进制字符串

String s1 = gbkToUtf8("张`H2CC56。,,.");
String s2 = gbkToUtf8("你好");
Assertions.assertEquals("张𬱖。,,.", s1);
Assertions.assertEquals("你好", s2);String s = gbkToUtf8("崔`H9FBF");
Assertions.assertEquals("E5B494E9BEBF", bytesToHex(s.getBytes(StandardCharsets.UTF_8)));

gbk伪码转gb18030

  • 原理和【gbk伪码转utf8】类似
  • 将 GBK 伪码字符串还原成 GB18030 编码的字符串
public static String gbkToGb18030(String input)
  • 案例如下:
String s1 = gbkToGb18030("张`H2CC56。,,.");
String s2 = gbkToGb18030("你好");
Assertions.assertEquals("张𬱖。,,.", s1);
Assertions.assertEquals("你好", s2);String s = gbkToUtf8("崔`H9FBF");
Assertions.assertEquals("B4DE82359138", bytesToHex(s.getBytes(GB18030)));
http://www.lryc.cn/news/575412.html

相关文章:

  • 价格敏感带争夺战!澳洲电商双雄增长密码,3大本土护城河尚存
  • C# 项目使用obfuscar混淆
  • 华曦达港股IPO递表,AI Home生态构建智能生活新蓝图
  • 2025 Java开发生态全景图:云原生、AI与性能优化的技术融合
  • 广州华锐互动:技术与创意双驱动的 VR 先锋​
  • 基于组件的软件开发(CBSD)与面向服务的架构(SOA)的对比分析
  • Android-Layout Inspector使用手册
  • VSCode插件开发
  • Vue3 中 toRef 与 toRefs 的深度解析与实战应用
  • Sentinel 授权规则详解与自定义异常处理
  • 【机器学习第一期(Python)】梯度提升决策树 GBDT
  • 【机器学习第二期(Python)】优化梯度提升决策树 XGBoost
  • Linux命令-Searching-locate
  • Docker compoes与私有仓库部署
  • 基于vue3+ByteMD快速搭建自己的Markdown文档编辑器
  • Midscene.js:使用 LLMs.txt 快速生成 AI 自动化测试用例「喂饭教程」
  • [Andrej Karpathy] 大型语言模型作为新型操作系统
  • 华为OD 机试 2025-黑板上色
  • 【25软考网工】第十章 网络规划与设计(2)网络规划与分析、网络结构与功能
  • 如何进行 iOS App 混淆加固?IPA 加壳与资源保护实战流程
  • 如何将视频从 iPhone 发送到 Android 设备
  • 数字孪生技术驱动UI前端变革:从静态展示到动态交互的飞跃
  • uniapp 和原生插件交互
  • 小程序入门:理解小程序页面配置
  • vue + vue-router写登陆验证的同步方法和异步方法,及页面组件的分离和后端代码
  • 命名数据网络 | 数据包(Data Packet)
  • chili3d笔记23 正交投影3d重建笔记4 点到线2
  • 【NLP】使用 LangGraph 构建 RAG 的Research Multi-Agent
  • house of apple2
  • Linux系统(信号篇):信号的产生