Java 按字符为单位截取

背景

            按长度截取字符功能是为了解决什么问题呢?首先了解下两个维度的基础

           1. Java中很多工具类在按长度截取文本的时候,中文/英文/数字/中英文标点符号每一个都代表一个长度,比如subString方法

           2. 一个中文和英文数字所占的内存和显示的大小也不同,中文和英文数字宽度不同如下➡️:  宽度   kd

问题

           当UI或者功能要求按长宽高等固定尺寸来作为衡量标准的时候,那么长度就不能作为我们的衡量标准,因为1个中文长度是1个单位,1个数字长度也是1个单位,而实际他们所占的尺寸是不同的,那么怎么解决呢?我们就得找一个统一的衡量标准,也就是字符

按字符为单位截取

public class TextUtils {
    /**
     * 按字符截取长度
     *
     * @param text 原文本
     * @param maxLength 截取长度(按字符)
     * @return
     */
    public static String subStringByChar(String text, Integer maxLength){
        if (StringUtils.isBlank(text)) {
            return text;
        }
        //名称最多展示14个字符,一个汉字算两个字符,超过展示...
        StringBuilder sBuilder = new StringBuilder();
        char[] chars = text.toCharArray();
        int length = 0;
        for (char ch : chars){
            boolean chineseChar = isChineseChar(ch) || isSymbol(ch);
            length = length + (chineseChar ? 2 : 1);
            if (length > maxLength){
                break;
            }
            sBuilder.append(ch);
        }
        String testResult = sBuilder.toString();
        if (length > maxLength){
            testResult = testResult + "...";
        }
        return testResult;
    }

    /**
     * 是否汉字字符
     * @param c
     * @return
     */
    private static boolean isChineseChar(char c) {
        return String.valueOf(c).matches("[\u4e00-\u9fa5]");
    }

    /**
     * 是否中文符号
     * @param ch
     * @return
     */
    private static boolean isSymbol(char ch)
    {
        if(isCnSymbol(ch)) return true;
        if(isEnSymbol(ch))return true;

        if(0x2010 <= ch && ch <= 0x2017) return true;
        if(0x2020 <= ch && ch <= 0x2027) return true;
        if(0x2B00 <= ch && ch <= 0x2BFF) return true;
        if(0xFF03 <= ch && ch <= 0xFF06) return true;
        if(0xFF08 <= ch && ch <= 0xFF0B) return true;
        if(ch == 0xFF0D || ch == 0xFF0F) return true;
        if(0xFF1C <= ch && ch <= 0xFF1E) return true;
        if(ch == 0xFF20 || ch == 0xFF65) return true;
        if(0xFF3B <= ch && ch <= 0xFF40) return true;
        if(0xFF5B <= ch && ch <= 0xFF60) return true;
        if(ch == 0xFF62 || ch == 0xFF63) return true;
        if(ch == 0x0020 || ch == 0x3000) return true;
        return false;

    }
    private static boolean isCnSymbol(char ch) {
        if (0x3004 <= ch && ch <= 0x301C) return true;
        if (0x3020 <= ch && ch <= 0x303F) return true;
        return false;
    }
    private static boolean isEnSymbol(char ch){

        if (ch == 0x40) return true;
        if (ch == 0x2D || ch == 0x2F) return true;
        if (0x23 <= ch && ch <= 0x26) return true;
        if (0x28 <= ch && ch <= 0x2B) return true;
        if (0x3C <= ch && ch <= 0x3E) return true;
        if (0x5B <= ch && ch <= 0x60) return true;
        if (0x7B <= ch && ch <= 0x7E) return true;

        return false;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值