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

commons.box.util.Strs Maven / Gradle / Ivy

The newest version!
package commons.box.util;

import com.google.common.base.MoreObjects;
import com.google.common.base.MoreObjects.ToStringHelper;
import commons.box.app.AppError;
import commons.box.app.misc.EntitiesASCII;
import commons.box.app.misc.EntitiesHTML;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.nio.charset.Charset;
import java.util.*;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static java.util.stream.Collectors.joining;

/**
 * 字符串常用工具类
 * 

创建作者:xingxiuyi

*

版权所属:xingxiuyi

*/ public final class Strs { public static final String EMPTY = StringUtils.EMPTY; public static final String[] EMPTY_STRS = new String[]{}; public static final int INDEX_NOT_FOUND = -1; private Strs() { } // --------------- 相等判断 --------------- /** * 相等 * * @param a * @param b * @return */ public static boolean equals(final String a, final String b) { return Objects.equals(a, b); } /** * 忽略大小写 * * @param a * @param b * @return */ @SuppressWarnings("StringEquality") public static boolean equalsIgnoreCase(final String a, final String b) { return (a == b) || (a != null && a.equalsIgnoreCase(b)); } /** * 数字 * * @param cs * @return */ public static boolean isNumeric(final String cs) { return StringUtils.isNumeric(cs); } /** * 数字和空格 * * @param cs * @return */ public static boolean isNumericSpace(final String cs) { return StringUtils.isNumericSpace(cs); } /** * 是否为空格 * * @param cs * @return */ public static boolean isWhitespace(final String cs) { return StringUtils.isWhitespace(cs); } // --------------- 空字符串相关 --------------- /** * 是否为空 * * @param str * @return */ public static final boolean isEmpty(final String str) { return str == null || str.length() == 0; } /** * 不为空 * * @param str * @return */ public static boolean isNotEmpty(final String str) { return !isEmpty(str); } /** * 可能为空 * * @param css * @return */ public static boolean isAnyEmpty(final String... css) { return StringUtils.isAnyEmpty(css); } /** * 没有空 * * @param css * @return */ public static boolean isNoneEmpty(final String... css) { return !isAnyEmpty(css); } /** * 是否为空或仅包括空格等 * * @param cs * @return */ public static boolean isBlank(final String cs) { return StringUtils.isBlank(cs); } /** * 非空格 * * @param cs * @return */ public static boolean isNotBlank(final String cs) { return !isBlank(cs); } /** * 是否包含空格 * * @param css * @return */ public static boolean isAnyBlank(final String... css) { if (css == null || css.length < 1) return true; for (final String cs : css) if (isBlank(cs)) return true; return false; } /** * 是否无空格 * * @param css * @return */ public static boolean isNoneBlank(final String... css) { return !isAnyBlank(css); } /** * trim字符串 * * @param str * @return */ public static String trim(final String str) { return str == null ? null : str.trim(); } /** * trim字符串 第二个参数指示null或空字符串是否trim成空字符串 false时输出null * * @param str * @param toEmpty * @return */ public static String trim(final String str, final boolean toEmpty) { if (isBlank(str)) return (toEmpty) ? "" : null; return str.trim(); } /** * 清空前后字符串 与trim不同的是此方法将制表符等认为是空 一起清理 * * @param str * @return */ public static String strip(final String str) { return StringUtils.strip(str); } /** * 清空前后字符串 与trim不同的是此方法将制表符等认为是空 一起清理 第二个参数指示null或空字符串是否trim成空字符串 false时输出null * * @param str * @param toEmpty * @return */ public static String strip(final String str, final boolean toEmpty) { return toEmpty ? StringUtils.stripToEmpty(str) : StringUtils.stripToNull(str); } // --------------- 大小写操作 --------------- /** * 转为大写 * * @param s * @return */ public static String caseUpper(String s) { if (s == null) return null; return s.toUpperCase(Locale.ROOT); } /** * 转为小写 * * @param s * @return */ public static String caseLower(String s) { if (s == null) return null; return s.toLowerCase(Locale.ROOT); } // --------------- 字符串查找 --------------- /** * 查找 * * @param seq * @param searchSeq * @return */ public static int indexOf(final String seq, final String searchSeq) { if (seq == null || searchSeq == null) return INDEX_NOT_FOUND; return seq.indexOf(searchSeq); } /** * 查找 按给定位置开始 * * @param seq * @param searchSeq * @param startPos * @return */ public static int indexOf(final String seq, final String searchSeq, final int startPos) { if (seq == null || searchSeq == null) return INDEX_NOT_FOUND; return seq.indexOf(searchSeq, startPos); } /** * 查找 忽略大小写 * * @param str * @param searchStr * @return */ public static int indexOfIgnoreCase(final String str, final String searchStr) { return StringUtils.indexOfIgnoreCase(str, searchStr); // TODO 考虑使用原始String机制来实现 } /** * 查找 忽略大小写 按给定位置开始 * * @param str * @param searchStr * @param startPos * @return */ public static int indexOfIgnoreCase(final String str, final String searchStr, int startPos) { return StringUtils.indexOfIgnoreCase(str, searchStr, startPos);// TODO 考虑使用原始String机制来实现 } /** * 查找最后出现的位置 * * @param seq * @param searchSeq * @return */ public static int indexOfLast(final String seq, final String searchSeq) { if (seq == null || searchSeq == null) return INDEX_NOT_FOUND; return seq.lastIndexOf(searchSeq); } /** * 查找最后出现的位置 按给定位置开始 * * @param seq * @param searchSeq * @param startPos * @return */ public static int indexOfLast(final String seq, final String searchSeq, final int startPos) { if (seq == null || searchSeq == null) return INDEX_NOT_FOUND; return seq.lastIndexOf(searchSeq, startPos); } /** * 查找最后出现的位置 忽略大小写 * * @param str * @param searchStr * @return */ public static int indexOfLastIgnoreCase(final String str, final String searchStr) { return StringUtils.lastIndexOfIgnoreCase(str, searchStr);// TODO 考虑使用原始String机制来实现 } /** * 查找最后出现的位置 忽略大小写 按给定位置开始 * * @param str * @param searchStr * @param startPos * @return */ public static int indexOfLastIgnoreCase(final String str, final String searchStr, int startPos) { return StringUtils.lastIndexOfIgnoreCase(str, searchStr, startPos);// TODO 考虑使用原始String机制来实现 } /** * 是否按前缀开始 * * @param str * @param prefix * @return */ public static boolean startsWith(final String str, final String prefix) { return StringUtils.startsWith(str, prefix); } /** * 是否按前缀开始 忽略大小写 * * @param str * @param prefix * @return */ public static boolean startsWithIgnoreCase(final String str, final String prefix) { return StringUtils.startsWithIgnoreCase(str, prefix); } /** * 是否按后缀结束 忽略大小写 * * @param str * @param suffix * @return */ public static boolean endsWithIgnoreCase(final String str, final String suffix) { return StringUtils.endsWithIgnoreCase(str, suffix); } /** * 是否包含空白 * * @param seq * @return */ public static boolean hasWhitespace(final String seq) { return StringUtils.containsWhitespace(seq); } // --------------- 字符串分隔 --------------- /** * 按位置获取字串 * * @param str * @param start * @return */ public static String sub(final String str, int start) { return StringUtils.substring(str, start); } /** * 按位置截取字串 * * @param str * @param start * @param end * @return */ public static String sub(final String str, int start, int end) { return StringUtils.substring(str, start, end); } /** * 字串前的内容 * * @param str * @param separator * @return */ public static String subBefore(final String str, final String separator) { return StringUtils.substringBefore(str, separator); } /** * 字串后的内容 * * @param str * @param separator * @return */ public static String subAfter(final String str, final String separator) { return StringUtils.substringAfter(str, separator); } /** * 最后一个字串前的内容 * * @param str * @param separator * @return */ public static String subBeforeLast(final String str, final String separator) { return StringUtils.substringBeforeLast(str, separator); } /** * 最后一个字串后的内容 * * @param str * @param separator * @return */ public static String subAfterLast(final String str, final String separator) { return StringUtils.substringAfterLast(str, separator); } /** * 按前后缀分隔 只返回第一组符合结果的内容 * * @param str * @param open * @param close * @return */ public static String subBetween(final String str, final String open, final String close) { return StringUtils.substringBetween(str, open, close); } /** * 按前后缀分隔 * * @param str * @param open * @param close * @return */ public static String[] subsBetween(final String str, final String open, final String close) { if (str == null) return EMPTY_STRS; return StringUtils.substringsBetween(str, open, close); } /** * 左边字串 给定长度 * * @param str * @param len * @return */ public static String left(final String str, final int len) { return StringUtils.left(str, len); } /** * 右边字串 给定长度 * * @param str * @param len * @return */ public static String right(final String str, final int len) { return StringUtils.right(str, len); } /** * 中间字串 * * @param str * @param pos * @param len * @return */ public static String mid(final String str, int pos, final int len) { return StringUtils.mid(str, pos, len); } /** * 拼接 * * @param elements * @param * @return */ @SafeVarargs public static String join(final T... elements) { return StringUtils.join(elements); } /** * 拼接 * * @param array * @param separator * @return */ public static String join(final Object[] array, final String separator) { return StringUtils.join(array, separator); } /** * 拼接 * * @param iter * @param separator * @return */ public static String join(final Collection iter, final String separator) { return StringUtils.join(iter, separator); } /** * 拼接 * * @param iterator * @param separator * @return */ public static String join(final Iterator iterator, final String separator) { return StringUtils.join(iterator, separator); } /** * 删除空白 * * @param str * @return */ public static String removeWhitespace(final String str) { return StringUtils.deleteWhitespace(str); } /** * 删除字串 * * @param str * @param remove * @return */ public static String remove(final String str, final String remove) { return StringUtils.remove(str, remove); } /** * 替换 * * @param text * @param searchString * @param replacement * @return */ public static String replace(final String text, final String searchString, final String replacement) { return StringUtils.replace(text, searchString, replacement); } /** * 替换 * * @param text * @param searchString * @param replacement * @param max * @return */ public static String replace(final String text, final String searchString, final String replacement, int max) { return StringUtils.replace(text, searchString, replacement, max); } /** * 按正则替换 * * @param source * @param regex * @param replacement * @return */ public static String replacePattern(final String source, final String regex, final String replacement) { return RegExUtils.replacePattern(source, regex, replacement); } // --------------- 字符串编码与输出 --------------- public static byte[] bytes(String str) { return bytes(str, Langs.CHARSET_UTF8); } public static byte[] bytes(String str, Charset charset) { if (str == null) return null; if (charset == null) charset = Langs.CHARSET_UTF8; return str.getBytes(charset); } public static String get(byte[] bytes) { return get(bytes, Langs.CHARSET_UTF8); } public static String get(byte[] bytes, Charset charset) { if (bytes == null) return null; if (charset == null) charset = Langs.CHARSET_UTF8; return new String(bytes, charset); } public static String format(Object object, Object... param) { String p = Strs.toString(object); if (p == null) return null; return String.format(p, param); } public static String toString(Object object) { if (object == null) return null; else if (object.getClass().isArray()) return Arrays.toString((Object[]) object); return object.toString(); } public static String toString(final byte[] bytes, final Charset charset) { if (bytes == null) return null; return StringUtils.toEncodedString(bytes, charset); } public static ToStringHelper toStringHelper(Object object) { if (object == null) object = new Object(); return MoreObjects.toStringHelper(object); } //----------- FORK Strman (shekhargulati/strman-java) from : acdb15d6fe12ec25e5e0a15dba1c0f5c20db5588 private static final Predicate STRING_PREDICATE_NULL = Objects::isNull; private static final Supplier STRING_MSG_SUPPLIER_NULL = () -> "值不允许为空"; private static final Supplier STRING_MSG_SUPPLIER_INVALID = () -> "值不符合要求"; /** * 验证规则: 是否为空 * * @throws AppError */ public static void valid(String str) throws AppError { valid(str, STRING_PREDICATE_NULL, STRING_MSG_SUPPLIER_NULL); } /** * @param str * @param predicate * @throws AppError */ public static void valid(String str, Predicate predicate) throws AppError { valid(str, predicate, STRING_MSG_SUPPLIER_INVALID); } /** * 验证字符串 * * @param str * @param predicate * @param msg * @throws AppError */ public static void valid(String str, Predicate predicate, Supplier msg) throws AppError { valid(str, predicate, msg); } /** * 合并数组的字符串 以sp分隔 * * @param strs * @param sp * @param trim * @return */ @Nonnull public static String combine(String[] strs, String sp, boolean trim) { if (strs == null) return ""; StringBuilder sb = new StringBuilder(); for (int i = 0; i < strs.length; i++) { String s = strs[i]; if (trim) s = Strs.trim(s, true); sb.append(s); if (i < (strs.length - 1)) sb.append(sp); } return sb.toString(); } /** * 合并数组的字符串 以sp分隔 * * @param strs * @param trim * @return */ @Nonnull public static String combine(String[] strs, boolean trim) { return combine(strs, " ", trim); } /** * 合并数组的字符串 以sp分隔 * * @param strs * @return */ @Nonnull public static String combine(String[] strs) { return combine(strs, " ", true); } /** * Append字符串 类似于StringBuilder的append * * @param value 原始字符串 * @param appends 增加的目标字符串(对象以toString方式解析) * @return 返回后的字符串 */ public static String append(final String value, final Object... appends) { if (value == null) return null; if (appends == null || appends.length == 0) return value; StringJoiner joiner = new StringJoiner(""); for (Object append : appends) joiner.add((append != null) ? append.toString() : null); return value + joiner.toString(); } /** * 获取index位置的字符 如果未找到或者index超出范围则返回Optional empty * * @param value 输入 * @param index 位置 * @return Optional String (未找到返回empty) */ public static Optional at(final String value, int index) { if (value == null || value.isEmpty()) return Optional.empty(); int length = value.length(); if (index < 0) index = length + index; return (index < length && index >= 0) ? Optional.of(String.valueOf(value.charAt(index))) : Optional.empty(); } /** * 返回数组,每个元素是start和end之间的内容 * * @param value input * @param start start * @param end end * @return 包含每个start和end之间的内容 */ public static String[] between(final String value, final String start, final String end) { if (value == null || start == null || end == null) return EMPTY_STRS; String[] parts = value.split(end); return Arrays.stream(parts).map(subPart -> subPart.substring(subPart.indexOf(start) + start.length())).toArray(String[]::new); } /** * 返回数组,每个元素是str的数组 * * @param value input * @return 字符数组 */ public static String[] chars(final String value) { return value.split(""); } /** * 合并空格 所有的连续空格将被合并为一个空格符 * * @param value 原始字符串 * @return 组合后的字符串 */ public static String collapseWhitespace(final String value) { if (value == null) return null; return value.trim().replaceAll("\\s\\s+", " "); } /** * 是否包含给定字符串 * * @param value to search * @param needle to find * @return 找到为true */ public static boolean contains(final String value, final String needle) { return contains(value, needle, true); } /** * 是否包含给定字符串 忽略大小写 * * @param value 原始字符串 * @param needle 要查找的字符串 * @return 找到为true */ public static boolean containsIgnoreCase(final String value, final String needle) { return contains(value, needle, false); } /** * 是否包含给定字符串 按需忽略大小写 * * @param value 原始字符串 * @param needle 要查找的字符串 * @param caseSensitive 是否大小写敏感 * @return 找到为true */ public static boolean contains(final String value, final String needle, final boolean caseSensitive) { if (value == null || needle == null) return false; if (caseSensitive) return value.contains(needle); return value.toLowerCase().contains(needle.toLowerCase()); } /** * 验证是否包含全部给定字符串 * * @param value 原始字符串 * @param needles 要查找的字符串数组 * @return 如果全部包含则返回true, 否则返回false */ public static boolean containsAll(final String value, final String[] needles) { return !(value == null || needles == null) && Arrays.stream(needles).allMatch(needle -> contains(value, needle)); } /** * 验证是否包含全部给定字符串 * * @param value 原始字符串 * @param needles 要查找的字符串数组 * @param caseSensitive 是否大小写敏感 * @return 如果全部包含则返回true, 否则返回false */ public static boolean containsAll(final String value, final String[] needles, final boolean caseSensitive) { return !(value == null || needles == null) && Arrays.stream(needles).allMatch(needle -> contains(value, needle, caseSensitive)); } /** * 验证是否包含全部给定字符串中的任意一个 * * @param value 原始字符串 * @param needles 要查找的字符串数组 * @return 如果包含任意一个则返回true, 否则返回false */ public static boolean containsAny(final String value, final String[] needles) { return containsAny(value, needles, false); } /** * 验证是否包含全部给定字符串中的任意一个 * * @param value 原始字符串 * @param needles 要查找的字符串数组 * @param caseSensitive 是否大小写敏感 * @return 如果包含任意一个则返回true, 否则返回false */ public static boolean containsAny(final String value, final String[] needles, final boolean caseSensitive) { return !(value == null || needles == null) && Arrays.stream(needles).anyMatch(needle -> contains(value, needle, caseSensitive)); } /** * 统计出现次数 * * @param value 原始字符串 * @param subStr 要查找的字符串 * @return 字符串出现次数 */ public static long countSubstr(final String value, final String subStr) { return countSubstr(value, subStr, true, false); } /** * 统计出现次数 * * @param value 原始字符串 * @param subStr 要查找的字符串 * @param caseSensitive 是否大小写敏感 * @param allowOverlapping boolean to take into account overlapping * @return 字符串出现次数 */ public static long countSubstr(final String value, final String subStr, final boolean caseSensitive, boolean allowOverlapping) { if (value == null || subStr == null) return 0L; return countSubstr(caseSensitive ? value : value.toLowerCase(), caseSensitive ? subStr : subStr.toLowerCase(), allowOverlapping, 0L); } /** * 是否以search字符串结尾 * * @param value 原始字符串 * @param search 要查找的字符串 * @return 是否以目标结尾 */ public static boolean endsWith(final String value, final String search) { return endsWith(value, search, value.length(), true); } /** * 是否以search字符串结尾 * * @param value 原始字符串 * @param search 要查找的字符串 * @param caseSensitive 是否大小写敏感 * @return 是否以目标结尾 */ public static boolean endsWith(final String value, final String search, final boolean caseSensitive) { if (value == null || search == null) return false; return endsWith(value, search, value.length(), caseSensitive); } /** * 是否以search字符串结尾 * * @param value 原始字符串 * @param search 要查找的字符串 * @param position 查找的开始位置 * @param caseSensitive 是否大小写敏感 * @return 是否以目标结尾 */ public static boolean endsWith(final String value, final String search, final int position, final boolean caseSensitive) { if (value == null || search == null) return false; int remainingLength = position - search.length(); if (caseSensitive) return value.indexOf(search, remainingLength) > -1; return value.toLowerCase().indexOf(search.toLowerCase(), remainingLength) > -1; } /** * 确定字符串以prefix开头(left) 如未包含前缀则自动增加前缀 * * @param value 输入 * @param prefix 前缀 * @return 返回已prefix开头的字符串, 如果原字符串未以prefix开头则增加此prefix */ public static String ensureLeft(final String value, final String prefix) { return ensureLeft(value, prefix, true); } /** * 确定字符串以prefix开头(left) 如未包含前缀则自动增加前缀 * * @param value 输入 * @param prefix 前缀 * @param caseSensitive 是否大小写敏感 * @return 返回已prefix开头的字符串, 如果原字符串未以prefix开头则增加此prefix */ public static String ensureLeft(final String value, final String prefix, final boolean caseSensitive) { if (value == null || prefix == null) return value; if (caseSensitive) return value.startsWith(prefix) ? value : prefix + value; String _value = value.toLowerCase(); String _prefix = prefix.toLowerCase(); return _value.startsWith(_prefix) ? value : prefix + value; } /** * 确定字符串以suffix结尾(right) 如未包含前缀则自动增加前缀 * * @param value 输入 * @param suffix 后缀 * @return 返回已suffix结尾的字符串, 如果原字符串未以suffix结尾则增加此suffix结尾 */ public static String ensureRight(final String value, final String suffix) { return ensureRight(value, suffix, true); } /** * 确定字符串以suffix结尾(right) 如未包含前缀则自动增加前缀 * * @param value 输入 * @param suffix 后缀 * @param caseSensitive 是否大小写敏感 * @return 返回已suffix结尾的字符串, 如果原字符串未以suffix结尾则增加此suffix结尾 */ public static String ensureRight(final String value, final String suffix, boolean caseSensitive) { if (value == null || suffix == null) return value; return endsWith(value, suffix, caseSensitive) ? value : append(value, suffix); } /** * 返回开头的n个字符 * * @param value 输入 * @param n 前n个 * @return 开头的n个字符 */ public static String first(final String value, final int n) { if (value == null || n < 0 || n > value.length()) return value; return value.substring(0, n); } /** * 开头的第一个字符 * * @param value 输入 * @return 开头的第一个字符 */ public static String head(final String value) { return first(value, 1); } /** * 格式化 *

* 当给定的参数不足时 用空字符串填充目标 * * @param value 原始模板 * @param params 参数 * @return 格式化后字符串 */ public static String format(final String value, String... params) { if (value == null) return null; Pattern p = Pattern.compile("\\{(\\w+)\\}"); Matcher m = p.matcher(value); String result = value; while (m.find()) { int paramNumber = Integer.parseInt(m.group(1)); String str = (params == null || paramNumber >= params.length) ? "" : params[paramNumber]; result = result.replace(m.group(), str); } return result; } /** * 返回出现needle子串的位置,如果定义了offset那么从offset位置开始查找,如果未找到则返回-1 * * @param value 输入 * @param needle 查找子串 * @param offset 开始查找的位置 * @param caseSensitive 是否大小写敏感 * @return 首次出现的位置 */ public static int indexOf(final String value, final String needle, int offset, boolean caseSensitive) { if (value == null || needle == null) return -1; if (caseSensitive) return value.indexOf(needle, offset); return value.toLowerCase().indexOf(needle.toLowerCase(), offset); } /** * 在给定位置插入字串 * * @param value 输入 * @param substr 要插入的子串 * @param index 要插入的位置 * @return 加工后的内容 */ public static String insert(final String value, final String substr, final int index) { if (value == null || substr == null) return value; if (index > value.length() || index < 0) return value; return append(value.substring(0, index), substr, value.substring(index)); } /** * 是否全为大写 * * @param value 输入 * @return 是否全为大写 */ public static boolean isUpperCase(final String value) { if (value == null) return false; for (int i = 0; i < value.length(); i++) { if (Character.isLowerCase(value.charAt(i))) return false; } return true; } /** * 是否全为小写 * * @param value 输入 * @return 是否全为小写 */ public static boolean isLowerCase(final String value) { if (value == null) return false; for (int i = 0; i < value.length(); i++) { if (Character.isUpperCase(value.charAt(i))) return false; } return true; } /** * 返回第n个结尾字符 * * @param value 输入 * @param n 个数n * @return n Last characters */ public static String last(final String value, int n) { if (value == null) return null; if (n > value.length() || n < 0) return value; return value.substring(value.length() - n); } /** * 左边 * * @param value 输入 * @param pad The pad * @param length Length of the String we want * @return Padded String */ public static String leftPad(final String value, final String pad, final int length) { if (value == null || pad == null || length < 0) return value; if (value.length() > length) return value; return append(repeat(pad, length - value.length()), value); } /** * 检测是否为字符串 * * @param value 输入 * @return 是否为字符串 */ public static boolean isString(final Object value) { if (value == null) return false; return value instanceof String; } /** * 最后一次出现查找子串的位置 * * @param value 输入 * @param needle 查找的字符串 * @return 最后一次出现查找子串的位置 */ public static int lastIndexOf(final String value, final String needle) { if (value == null || needle == null) return -1; return lastIndexOf(value, needle, value.length(), true); } /** * 最后一次出现查找子串的位置 * * @param value 输入 * @param needle 查找的字符串 * @param caseSensitive 是否 * @return 最后一次出现查找子串的位置 */ public static int lastIndexOf(final String value, final String needle, boolean caseSensitive) { if (value == null || needle == null) return -1; return lastIndexOf(value, needle, value.length(), caseSensitive); } /** * 最后一次出现查找子串的位置 * * @param value 输入 * @param needle 查找的字符串 * @param offset 位置 * @param caseSensitive 是否大小写敏感 * @return 最后一次出现查找子串的位置 */ public static int lastIndexOf(final String value, final String needle, final int offset, final boolean caseSensitive) { if (value == null || needle == null) return -1; if (caseSensitive) return value.lastIndexOf(needle, offset); return value.toLowerCase().lastIndexOf(needle.toLowerCase(), offset); } /** * 清除左边空格 * * @param value 输入 * @return 结果 */ public static String leftTrim(final String value) { if (value == null) return null; return value.replaceAll("^\\s+", ""); } /** * 返回长度 * * @param value 输入 * @return 长度 */ public static int length(final String value) { if (value == null) return -1; return value.length(); } /** * 染回增加前缀集合的结果 * * @param value 输入 * @param prepends 增加的字符串数组 * @return 操作后的值 */ public static String prepend(final String value, final String... prepends) { if (prepends == null || prepends.length == 0) return value; StringJoiner joiner = new StringJoiner(""); for (String prepend : prepends) joiner.add(prepend); return joiner.toString() + ((value == null) ? "" : value); } /** * 清理空的字符串元素 * * @param strings 原始数组 * @return 不包含空字符串的数组 */ public static String[] removeEmptyStrings(String[] strings) { if (strings == null || strings.length < 1) return EMPTY_STRS; return Arrays.stream(strings).filter(str -> str != null && !str.trim().isEmpty()).toArray(String[]::new); } /** * 删除左边前缀 * * @param value 输入 * @param prefix 删除的前缀 * @return 结果 */ public static String removeLeft(final String value, final String prefix) { return removeLeft(value, prefix, true); } /** * 删除左边前缀 * * @param value 输入 * @param prefix 删除的前缀 * @param caseSensitive 大小写标识 * @return 结果 */ public static String removeLeft(final String value, final String prefix, final boolean caseSensitive) { if (value == null || prefix == null) return value; if (caseSensitive) return value.startsWith(prefix) ? value.substring(prefix.length()) : value; return value.toLowerCase().startsWith(prefix.toLowerCase()) ? value.substring(prefix.length()) : value; } /** * 删除所有非word字符 * * @param value 输入 * @return 结果 */ public static String removeNonWords(final String value) { if (value == null) return null; return value.replaceAll("[^\\w]+", ""); } /** * 删除右边结尾 * * @param value 输入 * @param suffix 要删除的后缀 * @return 不包含后缀的结果 */ public static String removeRight(final String value, final String suffix) { return removeRight(value, suffix, true); } /** * 删除右边结尾 * * @param value 输入 * @param suffix 要删除的后缀 * @param caseSensitive 是否大小写敏感 or not * @return 不包含后缀的结果 */ public static String removeRight(final String value, final String suffix, final boolean caseSensitive) { if (value == null || suffix == null) return value; return endsWith(value, suffix, caseSensitive) ? value.substring(0, value.toLowerCase().lastIndexOf(suffix.toLowerCase())) : value; } /** * 删除所有空格 * * @param value 输入 * @return 无空格的字符串 */ public static String removeSpaces(final String value) { if (value == null) return null; return value.replaceAll("\\s", ""); } /** * 重复给定次数 * * @param value 输入 * @param multiplier 次数 * @return 结果 */ public static String repeat(final String value, final int multiplier) { if (value == null || multiplier < 1) return null; else if (multiplier == 1) return value; return Stream.generate(() -> value).limit(multiplier).collect(joining()); } /** * 替换给定字符串 * * @param value 输入 * @param search 查找 * @param newValue 替换 * @param caseSensitive 是否大小写敏感 or not * @return 结果 */ public static String replace(final String value, final String search, final String newValue, final boolean caseSensitive) { if (value == null || search == null) return value; if (caseSensitive) return value.replace(search, newValue); return Pattern.compile(search, Pattern.CASE_INSENSITIVE).matcher(value).replaceAll(Matcher.quoteReplacement(newValue)); } /** * 反转 * * @param value 输入 * @return 反转 */ public static String reverse(final String value) { if (value == null) return null; return new StringBuilder(value).reverse().toString(); } /** * 填充右边 * * @param value 输入 * @param length 长度 * @param pad 重复的字符串 * @return 结果 */ public static String rightPad(final String value, String pad, final int length) { if (value == null) return null; if (value.length() > length) return value; return append(value, repeat(pad, length - value.length())); } /** * 删除右侧空格 * * @param value 字符串 * @return 结果 */ public static String rightTrim(final String value) { if (value == null) return null; return value.replaceAll("\\s+$", ""); } /** * 安全截断字符串,超出商都的部分会被忽略,同时在返回结果中以类似 ... 结尾字串结尾的标识符 *

* 长度未超过限制直接返回原有字符串 *

* 此方法不会打断最后一个单词 * * @param value 输入 * @param length 最大长度 * @param filler 要附加的省略符号,例如: '...' * @return 结果 */ public static String truncateSafely(final String value, final int length, final String filler) { if (value == null) return null; if (length == 0) return ""; if (length >= value.length()) return value; String[] words = words(value); StringJoiner result = new StringJoiner(" "); int spaceCount = 0; for (String word : words) { if (result.length() + word.length() + filler.length() + spaceCount > length) { break; } else { result.add(word); spaceCount++; } } return append(result.toString(), filler); } /** * 安全截断字符串,超出商都的部分会被忽略,同时在返回结果中以类似 ... 结尾字串结尾的标识符 *

* 长度未超过限制直接返回原有字符串 *

* 此方法直接按长度操作,最后一个单词可能会被打断,与truncateSafely相比此方法性能稍好 * * @param value 输入 * @param length 最大长度 * @param filler 要附加的省略符号,例如: '...' * @return 结果 */ public static String truncate(final String value, final int length, final String filler) { if (value == null) return null; if (length == 0) return ""; if (length >= value.length()) return value; return append(value.substring(0, length - filler.length()), filler); } /** * 分隔 * * @param value 输入 * @param regex 查询Regex * @return 返回结果 */ @Nonnull public static String[] split(final String value, final String regex) { return split(value, regex, false); } /** * 分隔 是否 trim 元素,此方法中 null 字符串会转换成 "" * * @param value * @param regex * @param trim * @return */ @Nonnull public static String[] split(final String value, final String regex, boolean trim) { if (value == null) return EMPTY_STRS; String[] s = value.split(regex); if (trim) for (int i = 0; i < s.length; i++) s[i] = trim(s[i], true); return s; } /** * 按单词分隔(英文分词) * * @param value 输入 * @return 结果 */ @Nonnull public static String[] words(final String value) { if (value == null) return EMPTY_STRS; return value.split("\\W+"); } /** * 编解码: MIME base64 * * @param value 内容 * @return 解码后的内容 */ public static String base64Decode(final String value) { if (value == null) return null; return new String(Base64.getDecoder().decode(value)); } /** * 编解码: MIME base64 * * @param value 内容 * @return 编码后的内容 */ public static String base64Encode(final String value) { if (value == null) return null; return Base64.getEncoder().encodeToString(value.getBytes()); } /** * 编解码: 二进制 decode(value, 16, 2); * * @param value 内容 * @return 解码后的内容 */ public static String binDecode(final String value) { return decode(value, 16, 2); } /** * 编解码: 二进制 encode(value, 16, 2); * * @param value 内容 * @return 编码后的内容 */ public static String binEncode(final String value) { return encode(value, 16, 2); } /** * 编解码: 十进制 decode(value, 5, 10); * * @param value 内容 * @return 解码后的内容 */ public static String decDecode(final String value) { return decode(value, 5, 10); } /** * 编解码: 十进制 encode(value, 5, 10); * * @param value 内容 * @return 编码后的内容 */ public static String decEncode(final String value) { return encode(value, 5, 10); } /** * 编解码: 十六进制 decode(value, 4, 16); * * @param value 内容 * @return 解码后的内容 */ public static String hexDecode(final String value) { return decode(value, 4, 16); } /** * 编解码: 十六进制 encode(value, 4, 16); * * @param value 内容 * @return 编码后的内容 */ public static String hexEncode(final String value) { return encode(value, 4, 16); } /** * 编解码: HTML * * @param encodedHtml 内容 * @return 解码后的内容 */ public static String htmlDecode(final String encodedHtml) { if (encodedHtml == null) return null; String[] entities = encodedHtml.split("&\\W+;"); return Arrays.stream(entities).map(EntitiesHTML.decodedEntities::get).collect(joining()); } /** * 编解码: HTML * * @param html 内容 * @return 编码后的内容 */ public static String htmlEncode(final String html) { if (html == null) return null; return html.chars().mapToObj(c -> "\\u" + String.format("%04x", c).toUpperCase()).map(EntitiesHTML.encodedEntities::get).collect(joining()); } /** * 乱序给定字符串 * * @param value 输入 * @return 乱序 */ public static String shuffle(final String value) { if (value == null) return null; String[] chars = chars(value); Random random = new Random(); for (int i = 0; i < chars.length; i++) { int r = random.nextInt(chars.length); String tmp = chars[i]; chars[i] = chars[r]; chars[r] = tmp; } return String.join("", chars); } /** * 子串 *

* 本方法提供了安全操作,如果 begin和end超出范围自动规范 如果子串长度小于等于0返回空字符串 * * @param value 输入 * @param begin 开始 * @param end 结尾 * @return 字符串 sliced! */ public static String slice(final String value, int begin, int end) { if (value == null) return null; if (begin < 0) begin = 0; if (end > value.length()) end = value.length(); int subLen = end - begin; if (subLen <= 0) return EMPTY; return value.substring(begin, end); } /** * 包围 * * @param value 输入 * @param prefix 前缀 * @param suffix 后缀 如果suffix为空则使用prefix * @return 字符串 with surround substrs! */ public static String surround(final String value, final String prefix, final String suffix) { if (value == null) return null; String _prefix = Optional.ofNullable(prefix).orElse(""); return append(_prefix, value, Optional.ofNullable(suffix).orElse(_prefix)); } /** * 转换为 camelCase * * @param value 输入 * @return 转换为 camelCase. */ public static String toCamelCase(final String value) { if (value == null) return null; String str = toStudlyCase(value); return str.substring(0, 1).toLowerCase() + str.substring(1); } /** * 转换为 StudlyCaps. * * @param value 输入 * @return 转换为 StudlyCaps. */ public static String toStudlyCase(final String value) { if (value == null) return null; String[] words = collapseWhitespace(value.trim()).split("\\s*(_|-|\\s)\\s*"); return Arrays.stream(words).filter(w -> !w.trim().isEmpty()).map(w -> head(w).toUpperCase() + tail(w)).collect(joining()); } /** * tail字符串 * * @param value 输入 * @return 结果 */ public static String tail(final String value) { if (value == null) return null; return last(value, value.length() - 1); } /** * Decamelize 字符串 * * @param value 输入 * @param chr string to use * @return String decamelized. */ public static String toDecamelize(final String value, final String chr) { String camelCasedString = toCamelCase(value); String[] words = camelCasedString.split("(?=\\p{Upper})"); return Arrays.stream(words).map(String::toLowerCase).collect(joining(Optional.ofNullable(chr).orElse(" "))); } /** * 转为 kebab-case. * * @param value 输入 * @return kebab-case结果 */ public static String toKebabCase(final String value) { return toDecamelize(value, "-"); } /** * 转为蛇形 * * @param value 输入 * @return 蛇形大小写 */ public static String toSnakeCase(final String value) { return toDecamelize(value, "_"); } /** * 解码为指定进制 2 8 10 16等 * * @param value * @param digits 位数 * @param radix 进制 * @return */ public static String decode(final String value, final int digits, final int radix) { if (value == null) return null; return Arrays.stream(value.split("(?<=\\G.{" + digits + "})")) .map(data -> String.valueOf(Character.toChars(Integer.parseInt(data, radix)))) .collect(joining()); } /** * 编码为指定进制 2 8 10 16等 * * @param value * @param digits 位数 * @param radix 进制 * @return */ public static String encode(final String value, final int digits, final int radix) { if (value == null) return null; return value.chars().mapToObj(ch -> leftPad(Integer.toString(ch, radix), "0", digits)).collect(joining()); } /** * slug字符串 * * @param value 字符串 * @return slug字符串 */ public static String slugify(final String value) { if (value == null) return null; String transliterated = transliterate(collapseWhitespace(value.trim().toLowerCase())); return String.join("-", words(transliterated.replace("&", "-and-"))); } /** * 删除无效字符 * * @param value 输入 * @return 结果 */ public static String transliterate(final String value) { if (value == null) return null; String result = value; Set>> entries = EntitiesASCII.ascii.entrySet(); for (Map.Entry> entry : entries) { for (String ch : entry.getValue()) result = result.replace(ch, entry.getKey()); } return result; } private static long countSubstr(String value, String subStr, boolean allowOverlapping, long count) { int position = value.indexOf(subStr); if (position == -1) { return count; } int offset; if (!allowOverlapping) { offset = position + subStr.length(); } else { offset = position + 1; } return countSubstr(value.substring(offset), subStr, allowOverlapping, ++count); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy