RuoYi
2026-04-14 7a4f61cf5e8d42d24907ccc3d7345d25012d3a55
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/StringUtils.java
@@ -1,8 +1,12 @@
package com.ruoyi.common.core.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.Strings;
import org.springframework.util.AntPathMatcher;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.text.StrFormatter;
@@ -12,6 +16,7 @@
 * 
 * @author ruoyi
 */
@SuppressWarnings("deprecation")
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
    /** 空字符串 */
@@ -19,6 +24,9 @@
    /** 下划线 */
    private static final char SEPARATOR = '_';
    /** 星号 */
    private static final char ASTERISK = '*';
    /**
     * 获取参数不为空值
@@ -161,6 +169,49 @@
    }
    /**
     * 替换指定字符串的指定区间内字符为"*"
     *
     * @param str 字符串
     * @param startInclude 开始位置(包含)
     * @param endExclude 结束位置(不包含)
     * @return 替换后的字符串
     */
    public static String hide(CharSequence str, int startInclude, int endExclude)
    {
        if (isEmpty(str))
        {
            return NULLSTR;
        }
        final int strLength = str.length();
        if (startInclude > strLength)
        {
            return NULLSTR;
        }
        if (endExclude > strLength)
        {
            endExclude = strLength;
        }
        if (startInclude > endExclude)
        {
            // 如果起始位置大于结束位置,不替换
            return NULLSTR;
        }
        final char[] chars = new char[strLength];
        for (int i = 0; i < strLength; i++)
        {
            if (i >= startInclude && i < endExclude)
            {
                chars[i] = ASTERISK;
            }
            else
            {
                chars[i] = str.charAt(i);
            }
        }
        return new String(chars);
    }
    /**
     * 截取字符串
     * 
     * @param str 字符串
@@ -238,6 +289,32 @@
    }
    /**
     * 在字符串中查找第一个出现的 `open` 和最后一个出现的 `close` 之间的子字符串
     *
     * @param str 要截取的字符串
     * @param open 起始字符串
     * @param close 结束字符串
     * @return 截取结果
     */
    public static String substringBetweenLast(final String str, final String open, final String close)
    {
        if (isEmpty(str) || isEmpty(open) || isEmpty(close))
        {
            return NULLSTR;
        }
        final int start = str.indexOf(open);
        if (start != INDEX_NOT_FOUND)
        {
            final int end = str.lastIndexOf(close);
            if (end != INDEX_NOT_FOUND)
            {
                return str.substring(start + open.length(), end);
            }
        }
        return NULLSTR;
    }
    /**
     * 判断是否为空,并且不是空白字符
     * 
     * @param str 要判断的value
@@ -292,6 +369,299 @@
    public static boolean ishttp(String link)
    {
        return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
    }
    /**
     * 字符串转set
     *
     * @param str 字符串
     * @param sep 分隔符
     * @return set集合
     */
    public static final Set<String> str2Set(String str, String sep)
    {
        return new HashSet<String>(str2List(str, sep, true, false));
    }
    /**
     * 字符串转list
     *
     * @param str 字符串
     * @param sep 分隔符
     * @return list集合
     */
    public static final List<String> str2List(String str, String sep)
    {
        return str2List(str, sep, true, false);
    }
    /**
     * 字符串转list
     *
     * @param str 字符串
     * @param sep 分隔符
     * @param filterBlank 过滤纯空白
     * @param trim 去掉首尾空白
     * @return list集合
     */
    public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
    {
        List<String> list = new ArrayList<String>();
        if (StringUtils.isEmpty(str))
        {
            return list;
        }
        // 过滤空白字符串
        if (filterBlank && StringUtils.isBlank(str))
        {
            return list;
        }
        String[] split = str.split(sep);
        for (String string : split)
        {
            if (filterBlank && StringUtils.isBlank(string))
            {
                continue;
            }
            if (trim)
            {
                string = string.trim();
            }
            list.add(string);
        }
        return list;
    }
    /**
     * 检查子字符串是否存在
     *
     * @param seq 检查的字符串
     * @param searchSeq 查找的字符串
     * @return 结果
     */
    public static boolean contains(final CharSequence seq, final CharSequence searchSeq)
    {
        return Strings.CS.contains(seq, searchSeq);
    }
    /**
     * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
     *
     * @param collection 给定的集合
     * @param array 给定的数组
     * @return 结果
     */
    public static boolean containsAny(Collection<String> collection, String... array)
    {
        if (isEmpty(collection) || isEmpty(array))
        {
            return false;
        }
        else
        {
            for (String str : array)
            {
                if (collection.contains(str))
                {
                    return true;
                }
            }
            return false;
        }
    }
    /**
     * 判断是否包含给定数组中的任意一个。
     *
     * @param cs 要判断的字符串
     * @param searchCharSequences 要判断的数组
     * @return 结果
     */
    public static boolean containsAny(final CharSequence cs, final CharSequence... searchCharSequences)
    {
        return Strings.CS.containsAny(cs, searchCharSequences);
    }
    /**
     * 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
     *
     * @param cs 指定字符串
     * @param searchCharSequences 需要检查的字符串数组
     * @return 是否包含任意一个字符串
     */
    public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
    {
        if (isEmpty(cs) || isEmpty(searchCharSequences))
        {
            return false;
        }
        for (CharSequence testStr : searchCharSequences)
        {
            if (containsIgnoreCase(cs, testStr))
            {
                return true;
            }
        }
        return false;
    }
    /**
     * 检查是否包含要搜索的字符串,忽略大小写
     *
     * @param str 要检查的字符串
     * @param searchStr 要查找的字符串
     * @return 如果包含要搜索的字符串(忽略大小写)则返回true,如果不包含或返回false
     */
    public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr)
    {
        return Strings.CI.contains(str, searchStr);
    }
    /**
     * 检查字符串是否以任意前缀开始
     *
     * @param sequence 要检查的字符串
     * @param searchStrings 区分大小写的字符串前缀数组
     * @return 结果
     */
    public static boolean startsWithAny(final CharSequence sequence, final CharSequence... searchStrings)
    {
        return Strings.CS.startsWithAny(sequence, searchStrings);
    }
    /**
     * 不区分大小写地检查一个字符串是否以指定前缀开头。
     *
     * @param str 待检查的字符串
     * @param 要查找的前缀
     * @return 结果
     */
    public static boolean startsWithIgnoreCase(final CharSequence str, final CharSequence prefix)
    {
        return Strings.CI.startsWith(str, prefix);
    }
    /**
     * 比较两个字符串是否相同
     *
     * @param cs1 第一个字符串
     * @param cs2 第二个字符串
     * @return 如果给定对象与字符串相等,则返回 true;否则返回 false
     */
    public static boolean equals(final CharSequence cs1, final CharSequence cs2)
    {
        return Strings.CS.equals(cs1, cs2);
    }
    /**
     * 替换字符串中所有匹配的字符
     *
     * @param text 要搜索和替换的文本
     * @param searchString 要搜索的字符串
     * @param replacement  用于替换的字符串
     * @return 处理完所有替换后的文本
     */
    public static String replace(final String text, final String searchString, final String replacement)
    {
        return Strings.CS.replace(text, searchString, replacement);
    }
    /**
     * 仅当子字符串位于源字符串末尾时才将其移除,否则返回源字符串。
     * @param str 要搜索的源字符串
     * @param remove 要搜索并移除的字符串
     * @return 如果找到并移除了字符串,则返回移除后的子字符串
     */
    public static String removeEnd(final String str, final String remove)
    {
        return Strings.CS.removeEnd(str, remove);
    }
    /**
     * 查找字符串首次出现位置的索引
     *
     * @param seq 要检查的字符串
     * @param searchSeq 要查找的字符串
     * @return 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1
     */
    public static int indexOf(final CharSequence seq, final CharSequence searchSeq)
    {
        return Strings.CS.indexOf(seq, searchSeq);
    }
    /**
     * 检查字符串是否以指定的后缀结尾
     *
     * @param str 要检查的字符
     * @param suffix 要检查的后缀
     * @return 若参数与该字符串末尾相符 true;否则 false
     */
    public static boolean endsWith(final CharSequence str, final CharSequence suffix)
    {
        return Strings.CS.endsWith(str, suffix);
    }
    /**
     * 将给定的字符串与数组进行比较
     *
     * @param string 要比较的字符串
     * @param searchStrings 字符串数组
     * @return 如果字符串等于(区分大小写){@code searchStrings}中的任意其他元素,则返回true;如果{@code searchStrings}为null或不包含匹配项,则返回false
     */
    public static boolean equalsAny(final CharSequence string, final CharSequence... searchStrings)
    {
        return Strings.CS.equalsAny(string, searchStrings);
    }
    /**
     * 检查一个字符串是否以任意提供的区分大小写的后缀结尾。
     *
     * @param sequence 要检查的字符串
     * @param searchStrings 要查找的区分大小写的字符串数组
     * @return 如果输入参数{@code sequence}为null且未提供任何{@code searchStrings},或者输入{@code sequence}以任意提供的区分大小写的{@code searchStrings}结尾,则返回{@code true}。
     */
    public static boolean endsWithAny(final CharSequence sequence, final CharSequence... searchStrings)
    {
        return Strings.CS.endsWithAny(sequence, searchStrings);
    }
    /**
     * 不区分大小写地检查字符序列是否以指定的后缀结尾
     *
     * @param str 要检查的字符序列
     * @param suffix 要查找的后缀
     * @return 如果字符序列以该后缀结尾(不区分大小写),或两者均为{@code null},则返回{@code true}
     */
    public static boolean endsWithIgnoreCase(final CharSequence str, final CharSequence suffix)
    {
        return Strings.CI.endsWith(str, suffix);
    }
    /**
     * 指定范围内查找字符串,忽略大小写
     *
     * @param str 要检查的字符串
     * @param searchStr 要查找的字符串
     * @return 搜索字符串的第一个索引,如果未找到匹配项则返回 -1
     */
    public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
    {
        return Strings.CI.indexOf(str, searchStr);
    }
    /**
     * Compares given {@code string} to a CharSequences vararg of {@code searchStrings},
     * returning {@code true} if the {@code string} is equal to any of the {@code searchStrings}, ignoring case.
     *
     * @param string to compare, may be {@code null}.
     * @param searchStrings a vararg of strings, may be {@code null}.
     * @return {@code true} if the string is equal (case-insensitive) to any other element of {@code searchStrings};
     */
    public static boolean equalsAnyIgnoreCase(final CharSequence string, final CharSequence... searchStrings)
    {
        return Strings.CI.equalsAny(string, searchStrings);
    }
    /**
@@ -366,6 +736,22 @@
    }
    /**
     * 删除最后一个字符串
     *
     * @param str 输入字符串
     * @param spit 以什么类型结尾的
     * @return 截取后的字符串
     */
    public static String lastStringDel(String str, String spit)
    {
        if (!StringUtils.isEmpty(str) && str.endsWith(spit))
        {
            return str.subSequence(0, str.length() - 1).toString();
        }
        return str;
    }
    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
     * 
     * @param name 转换前的下划线大写方式命名的字符串
@@ -402,13 +788,18 @@
    }
    /**
     * 驼峰式命名法 例如:user_name->userName
     * 驼峰式命名法
     * 例如:user_name->userName
     */
    public static String toCamelCase(String s)
    {
        if (s == null)
        {
            return null;
        }
        if (s.indexOf(SEPARATOR) == -1)
        {
            return s;
        }
        s = s.toLowerCase();
        StringBuilder sb = new StringBuilder(s.length());
@@ -478,4 +869,53 @@
    {
        return (T) obj;
    }
}
    /**
     * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
     *
     * @param num 数字对象
     * @param size 字符串指定长度
     * @return 返回数字的字符串格式,该字符串为指定长度。
     */
    public static final String padl(final Number num, final int size)
    {
        return padl(num.toString(), size, '0');
    }
    /**
     * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
     *
     * @param s 原始字符串
     * @param size 字符串指定长度
     * @param c 用于补齐的字符
     * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
     */
    public static final String padl(final String s, final int size, final char c)
    {
        final StringBuilder sb = new StringBuilder(size);
        if (s != null)
        {
            final int len = s.length();
            if (s.length() <= size)
            {
                for (int i = size - len; i > 0; i--)
                {
                    sb.append(c);
                }
                sb.append(s);
            }
            else
            {
                return s.substring(len - size, len);
            }
        }
        else
        {
            for (int i = size; i > 0; i--)
            {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}