All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yixan.tools.common.util.StringUtil Maven / Gradle / Ivy

There is a newer version: 3.7.1
Show newest version
/*
 * 文  件  名:StringUtil.java
 * 版         权:Copyright 2012 JESHING Tech.Co.Ltd.All Rights Reserved.
 * 描         述:
 * 修  改  人:王波
 * 修改时间:2014-3-15
 * 修改内容:新增
 */
package com.yixan.tools.common.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializeWriter;
import com.alibaba.fastjson.serializer.SerializerFeature;

/**
 * 字符串工具类
 *
 * @author 王波
 * @version C01 2014-3-16
 * @since v1.0
 */
public final class StringUtil {

    /** 数字正则表达式 **/
    private static final Pattern DIGIT = Pattern.compile("([0-9]*)");

    /** 手机正则表达式 **/
    private static final Pattern PHONE = Pattern.compile("(1\\d{2})(\\d{4})(\\d{4})");

    /** 身份证正则表达式 **/
    private static final Pattern IDCARD = Pattern
            .compile("(^[1-9][0-9]{5}(19[0-9]{2}|20[01][0-9])(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])[0-9]{3}[0-9xX]$)");

    /** 邮箱正则表达式 **/
    private static final Pattern EMAIL = Pattern.compile("([-\\.\\w]+)(@)([-\\.\\w]+\\.\\w+)");

    /** 英文字符 **/
    private static final Pattern ASCII = Pattern.compile("[\\x00-\\xff]+");

    /** 网址正则表达式 **/
    private static final Pattern URL = Pattern.compile("^https?://.*");

    /** 正则表达式转义字符 **/
    private static final Pattern REG_CHAR = Pattern.compile("([\\{\\}\\[\\]\\(\\)\\^\\$\\.\\*\\?\\-\\+\\\\])");

    /** 字符串分隔符正则表达式 **/
    private static final Pattern SEPARATOR = Pattern.compile("\\|");

    // \\uD800\\uDC00-\\uDBFF\\uDFFF\\uD800-\\uDFFF
    private static final Pattern UTF8MB4 = Pattern.compile("[\\uD800\\uDC00-\\uDBFF\\uDFFF]");

    /** 构造函数 **/
    private StringUtil() {
    }

    /** 是否存在表情字符 **/
    public static boolean existEmoji(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return UTF8MB4.matcher(str).find();
    }

    /** 清除表情字符 **/
    public static String clearEmoji(String str) {
        return UTF8MB4.matcher(str).replaceAll("?");
    }

    /**
     * 判断字符串是不是手机号码
     *
     * @author zhaohuihua
     * @param str 字符串
     * @return 是不是手机号码, 如果字符串等于null或空字符串, 返回false
     */
    public static boolean isPhone(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return PHONE.matcher(str).matches();
    }

    /**
     * 验证是否为有效的身份证号
     * 
     * @author luyujian
     * @param str 参数
     * @return true:是 | false:否
     */
    public static boolean isIDCard(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return IDCARD.matcher(str).matches();
    }

    /**
     * 判断字符串是不是邮箱地址
     *
     * @author zhaohuihua
     * @param str 字符串
     * @return 是不是邮箱地址, 如果字符串等于null或空字符串, 返回false
     */
    public static boolean isEmail(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return EMAIL.matcher(str).matches();
    }

    /**
     * 判断字符串是不是网址
     *
     * @author zhaohuihua
     * @param str 字符串
     * @return 是不是网址, 如果字符串等于null或空字符串, 返回false
     */
    public static boolean isUrl(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return URL.matcher(str).matches();
    }

    /**
     * 判断字符串是不是数字
     *
     * @author zhaohuihua
     * @param str 字符串
     * @return 是不是数字, 如果字符串等于null或空字符串, 返回false
     */
    public static boolean isDigit(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        return DIGIT.matcher(str).matches();
    }

    /**
     * 判断string是否为null,或长度是否为0
     *
     * @param str 待判断的字符串
     *
     * @return 如果字符串为null,或长度为0,则返回true,否则返回false
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    /**
     * 判断string是否不为null并且长度大于0
     *
     * @param str 待判断的字符串
     *
     * @return 如果字符串不为null并且长度大于0,则返回true,否则返回false
     */
    public static boolean isNotEmpty(String str) {
        return str != null && str.length() > 0;
    }

    /**
     * 判断string数组是否存在空字符串(null,或长度为0)
     *
     * @author 赵卉华
     * @param str 待判断的字符串数组
     *
     * @return 如果存在空字符串,则返回true,否则返回false
     */
    public static boolean isAnyEmpty(String... str) {
        for (String s : str) {
            if (null == s || s.length() == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断两个字符串是不是相等
     *
     * @author zhaohuihua
     * @param o
     * @param n
     * @return
     */
    public static boolean equals(String o, String n) {
        if (o == null && n == null) {
            return true;
        } else if (o == null && n != null || o != null && n == null) {
            return false;
        } else {
            return o.equals(n);
        }
    }

    /**
     * 格式化, 实现参数替换
* 1. 占位符具有语义性
* 2. params可以直接由JSON转换而来
* *
     * String ptn = "尊敬的{nickName}:感谢注册!手机号码{phone}可作为登录账号使用.";
     * Map<String, Object> params = (JSONObject) JSON.toJSON(user);
     * String message = StringUtils.format(ptn, params);
     * 
* * @author 赵卉华 * @param string 原字符串 * @param params 参数键值对 * @return 参数替换后的字符串 */ public static String format(String string, Map params) { if (string == null || params == null || params.isEmpty()) { return string; } for (Map.Entry item : params.entrySet()) { String temp = item.getKey().trim(); String key; if (temp.startsWith("{") && temp.endsWith("}")) { key = temp; } else { key = "{" + temp + "}"; } // 替换正则表达式的转义字符, KEY不需要支持正则表达式 // 如果不替换, user.id这个点就会成为通配符 key = REG_CHAR.matcher(key).replaceAll("\\\\$1"); Object object = item.getValue(); String value = object == null ? "" : object.toString(); value = REG_CHAR.matcher(value).replaceAll("\\\\$1"); string = string.replaceAll(key, value); } return string; } /** * 格式化, 实现参数替换 * *
     * String ptn = "尊敬的{nickName}:感谢注册!手机号码{phone}可作为登录账号使用.";
     * String message = StringUtils.format(ptn, "nickName", user.getNickName(), "phone", user.getPhone());
     * 
* * @author 赵卉华 * @param string 原字符串 * @param params 参数键值对, 参数个数必须是2的倍数 * @return 参数替换后的字符串 */ public static String format(String string, Object... params) { if (string == null || params == null || params.length == 0) { return string; } if (params.length % 2 != 0) { throw new IllegalArgumentException("参数必须是键值对, 参数个数必须是2的倍数"); } Map map = new HashMap(); for (int i = 0; i < params.length;) { map.put(params[i++].toString(), params[i++]); } return format(string, map); } /** * 拆分字符串, 以竖杠|为分隔符
* 每一个子字符串都已经trim()过了
* "aa|bb|cc" --> [aa, bb, cc]
* "aa|bb||cc" --> [aa, bb, , cc] * * @param string 原字符串 * @return 拆分的字符串数组 */ public static String[] split(String string) { if (string == null) { return null; } String[] array = SEPARATOR.split(string); for (int i = 0; i < array.length; i++) { array[i] = array[i].trim(); } return array; } public static String remove(String string, int start, int end) { if (string == null) { return null; } StringBuilder buffer = new StringBuilder(); if (start > 0) { buffer.append(string.substring(0, start)); } if (end < string.length()) { buffer.append(string.substring(end)); } return buffer.toString(); } /** * 超过指定长度则省略中间字符
* 如果未超过指定长度则返回原字符, length小于20时省略最后部分而不是中间部分
* 如: 诺贝尔奖是以瑞典著名的 ... 基金创立的 * * @author 赵卉华 * @param text 长文本 * @param length 指定长度 * @return 省略中间部分的字符 */ public static String ellipsis(String text, int length) { if (text == null || text.length() <= length || length == 0) { return text; } String flag = " ... "; if (length < 20) { return text.substring(0, length) + flag; } int suffix = (length - flag.length()) / 4; int prefix = length - flag.length() - suffix; int end = text.length() - suffix; return text.substring(0, prefix) + flag + text.substring(end); } private static Pattern LOWER_CASE = Pattern.compile("[a-z]"); /** 如果全是大写字母, 则转换为小写字母 **/ public static String toLowerCaseIfAllUpperCase(String string) { if (string == null || string.length() == 0) { return string; } if (LOWER_CASE.matcher(string).find()) { return string; // 有小写字母, 不处理, 直接返回 } else { return string.toLowerCase(); // 整个字符串都没有小写字母则转换为小写字母 } } /** * 转换为驼峰命名法格式
* 如: user_name = userName, iuser_service = iuserService, i_user_service = iUserService * * @author zhaohuihua * @param name * @return */ public static String toCamelNaming(String name) { return toCamelNaming(name, false); } /** * 转换为驼峰命名法格式
* 如startsWithUpperCase=true时:
* user_name = UserName, iuser_service = IuserService, i_user_service = IUserService * * @author zhaohuihua * @param name * @param startsWithUpperCase 是否以大写字母开头 * @return */ public static String toCamelNaming(String name, boolean startsWithUpperCase) { if (name == null || name.length() == 0) { return name; } char[] chars = toLowerCaseIfAllUpperCase(name.trim()).toCharArray(); StringBuilder buffer = new StringBuilder(); boolean underline = startsWithUpperCase; for (char c : chars) { if (c == '_') { underline = true; } else { if (underline) { buffer.append(Character.toUpperCase(c)); } else { buffer.append(c); } underline = false; } } return buffer.toString(); } /** * 转换为下划线命名法格式
* 如: userName = user_name, SiteURL = site_url, IUserService = iuser_service
* user$Name = user$name, user_Name = user_name, user name = user_name * * @author zhaohuihua * @param name * @return */ public static String toUnderlineNaming(String name) { if (name == null || name.length() == 0) { return name; } char[] chars = name.trim().toCharArray(); boolean lastLowerCase = false; StringBuilder buffer = new StringBuilder(); for (char c : chars) { if (Character.isWhitespace(c)) { if (lastLowerCase) { buffer.append("_"); } lastLowerCase = false; } else if (Character.isUpperCase(c)) { if (lastLowerCase) { buffer.append("_"); } buffer.append(Character.toLowerCase(c)); lastLowerCase = false; } else { buffer.append(c); lastLowerCase = Character.isLowerCase(c); } } return buffer.toString(); } public static String concat(char c, String prefix, String... paths) { return concat(c, prefix, paths, 0, paths.length); } public static String concat(char c, String prefix, String[] paths, int start, int end) { StringBuilder buffer = new StringBuilder(); if (VerifyUtil.isNotBlank(prefix)) { buffer.append(prefix); } for (int i = Math.max(start, 0), len = Math.min(end, paths.length); i < len; i++) { String path = paths[i]; if (VerifyUtil.isBlank(path)) { continue; } if (!endsWithChar(buffer, c) && !startsWithChar(path, c)) { buffer.append(c).append(path); } else if (endsWithChar(prefix, c) && endsWithChar(path, c)) { buffer.append(path.substring(1)); } else { buffer.append(path); } } return buffer.toString(); } public static boolean endsWithChar(CharSequence string, char c) { return c == string.charAt(string.length() - 1); } public static boolean startsWithChar(CharSequence string, char c) { return c == string.charAt(0); } /** * 隐藏手机号码邮箱或名字, 如果不是手机号码和邮箱, 返回原字符串 * * @author 赵卉华 * @param text 手机号码邮箱或名字 * @return 隐藏后的字符串, 如: 139****1382, zh****[email protected],
* 黄山-〇山, 昆仑山-〇〇山, 黄山毛峰-〇〇毛峰, 超过四个字都只显示两个〇〇+最后两个字 */ public static String hidden(String text) { if (isEmpty(text)) { return text; } String ahide = "****"; String uhide = "\u3007"; // 〇 Matcher phone = PHONE.matcher(text); if (phone.matches()) { return phone.group(1) + ahide + phone.group(3); } Matcher email = EMAIL.matcher(text); if (email.matches()) { String prefix = email.group(1); String at = email.group(2); String suffix = email.group(3); return hiddenAscii(prefix, ahide) + at + suffix; } Matcher ascii = ASCII.matcher(text); if (ascii.matches()) { return hiddenAscii(text, ahide); } else { if (text.length() == 1) { return uhide + text; } if (text.length() == 2) { return uhide + text.substring(text.length() - 1); } else if (text.length() == 3) { return uhide + uhide + text.substring(text.length() - 1); } else { return uhide + uhide + text.substring(text.length() - 2); } } } private static String hiddenAscii(String string, String hide) { if (string.length() >= 4) { return string.substring(0, 2) + hide + string.substring(string.length() - 2); } else if (string.length() >= 2) { return string.substring(0, 1) + hide + string.substring(1); } else { return string + hide + string; } } /** * 根据手机号码或邮箱生成随机的昵称
* 如果原字符串为空, 返回原字符串
* 如果不是手机号码和邮箱, 返回原字符串+4位随机大写字母
* 如: 13913001382=139ADGK1382, [email protected]=zhaohuihuaQETU * * @author 赵卉华 * @param text 手机号码或邮箱 * @return 随机昵称 */ public static String generateRandomNickname(String text) { if (isEmpty(text)) { return text; } // 4位随机大写字母 String random = RandomUtil.generateString(4).toUpperCase(); Matcher phone = PHONE.matcher(text); if (phone.matches()) { return phone.group(1) + random + phone.group(3); } Matcher email = EMAIL.matcher(text); if (email.matches()) { return email.group(1) + random; } return text + random; } /** *

* Capitalizes a String changing the first letter to title case as per {@link Character#toTitleCase(char)}. No other * letters are changed. *

* *

* For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}. A * {@code null} input String returns {@code null}. *

* *
     * StringUtils.capitalize(null)  = null
     * StringUtils.capitalize("")    = ""
     * StringUtils.capitalize("cat") = "Cat"
     * StringUtils.capitalize("cAt") = "CAt"
     * 
* * @param str the String to capitalize, may be null * @return the capitalized String, {@code null} if null String input * @see org.apache.commons.lang3.text.WordUtils#capitalize(String) * @since 2.0 */ public static String capitalize(final String str) { int strLen; if (str == null || (strLen = str.length()) == 0) { return str; } char firstChar = str.charAt(0); if (Character.isTitleCase(firstChar)) { // already capitalized return str; } return new StringBuilder(strLen).append(Character.toTitleCase(firstChar)).append(str.substring(1)).toString(); } public static String trim(String string) { if (string == null || string.length() == 0) { return string; } else { return string.trim(); } } public static String trim(String string, char c) { return trim(string, c, true, true); } public static String trim(String string, char c, boolean left, boolean right) { char[] value = string.toCharArray(); int len = value.length; int st = 0; char[] val = value; if (left) { while ((st < len) && (val[st] == c)) { st++; } } if (right) { while ((st < len) && (val[len - 1] == c)) { len--; } } return ((st > 0) || (len < value.length)) ? string.substring(st, len) : string; } /** 左侧补零 **/ public static String pad(int number, int length) { return pad(String.valueOf(number), '0', true, length); } /** 左侧补零 **/ public static String pad(long number, int length) { return pad(String.valueOf(number), '0', true, length); } /** 左侧补空格 **/ public static String pad(String string, int length) { return pad(string, ' ', true, length); } /** * 左侧补字符
* pad("12345", '_', 10) 返回 _____12345
* * @param string * @param c * @param length * @return */ public static String pad(String string, char c, int length) { return pad(string, c, true, length); } /** * 左侧或右侧补字符
* pad("12345", '_', false, 10) 返回 12345_____
* * @param string * @param c * @param left 左侧补(true)还是右侧补(false) * @param length * @return */ public static String pad(String string, char c, boolean left, int length) { if (string == null || string.length() >= length) { return string; } char[] array = new char[length - string.length()]; Arrays.fill(array, c); return left ? new String(array) + string : string + new String(array); } /** * 统计子字符串出现次数 * * @param string 源字符串 * @param substring 子字符串 * @return 次数 */ public static int countSubstring(String string, String substring) { int count = 0; for (int i = 0; (i = string.indexOf(substring, i)) >= 0; i += substring.length()) { count++; } return count; } /** 是不是肯定的 **/ public static boolean isPositive(String value, boolean defValue) { if (VerifyUtil.isNotBlank(value) && isExists(true, value, "on", "yes", "true", "1")) { return true; } else { return defValue; } } /** 是不是否定的 **/ public static boolean isNegative(String value, boolean defValue) { if (VerifyUtil.isNotBlank(value) && isExists(true, value, "off", "no", "false", "0")) { return true; } else { return defValue; } } public static boolean isExists(String string, String... strings) { return isExists(false, string, strings); } public static boolean isNotExists(String string, String... strings) { return !isExists(false, string, strings); } public static boolean isExists(boolean ignoreCase, String string, String... strings) { if (strings == null || strings.length == 0) { return false; } for (String i : strings) { if (i == null && string == null) { return true; } else if (ignoreCase) { if (i != null && i.equalsIgnoreCase(string)) { return true; } else if (string != null && string.equalsIgnoreCase(i)) { return true; } } else { if (i != null && i.equals(string)) { return true; } else if (string != null && string.equals(i)) { return true; } } } return false; } public static boolean isNotExists(boolean ignoreCase, String string, String... strings) { return !isExists(ignoreCase, string, strings); } /** * 将对象转换为日志文本
* 如 toLogs(params, operator) 返回 \n\t{paramsJson} \n\t{operatorJson}
* * @param objects * @return */ public static String toLogs(Object... objects) { StringBuilder buffer = new StringBuilder(); for (Object object : objects) { buffer.append("\n\t"); if (object == null) { buffer.append("null"); } else if (object instanceof String) { buffer.append(object); } else { buffer.append(object.getClass().getSimpleName()).append(": "); buffer.append(toJsonString(object)); } } return buffer.toString(); } public static String toJsonString(Object object) { if (object == null) { return "null"; } try (SerializeWriter out = new SerializeWriter()) { JSONSerializer serializer = new JSONSerializer(out); serializer.config(SerializerFeature.QuoteFieldNames, false); serializer.config(SerializerFeature.WriteDateUseDateFormat, true); serializer.write(object); return out.toString(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy