Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
cn.buli_home.utils.common.StringUtils Maven / Gradle / Ivy
package cn.buli_home.utils.common;
import cn.buli_home.utils.constant.RegexConstant;
import cn.buli_home.utils.constant.StringConstant;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringUtils {
/**
* 判断是否为空
*/
public static boolean isEmpty(CharSequence str) {
return Objects.isNull(str) || str.length() == 0;
}
/**
* 判断是否为空(去空格)
*/
public static boolean isEmptyWithoutBlank(String str) {
return isEmpty(replaceBlank(str));
}
/**
* 去空白符
*/
public static String replaceBlank(CharSequence str) {
return replace(str.toString(), "\\s*|\t|\r|\n| ");
}
/**
* 字符串替换
*
* @param str 待替换字符串
* @param pattern 匹配规则
*/
public static String replace(String str, String pattern) {
if (isEmpty(str)) {
return StringConstant.EMPTY;
}
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(str);
return m.replaceAll(StringConstant.EMPTY);
}
/**
* 替换渲染模板:
* e.g. template: "My name is ${name} and I am ${age} years old."
* params: {"name": "mustard", "age": 18}
* result: My name is mustard and I am 18 years old.
*
* @param template 模板
* @param params 替换内容
*/
public static String replaceTemplate(String template, Map params) {
return replaceTemplate(template, params, null);
}
/**
* 替换渲染模板:
* e.g. template: "My name is ${name} and I am ${age} years old."
* params: {"name": "mustard", "age": 18}
* result: My name is mustard and I am 18 years old.
*
* @param template 模板
* @param params 替换内容
*/
public static String replaceTemplate(String template, Map params, List excludes) {
if (Objects.isNull(template) || Objects.isNull(params)) {
return null;
}
StringBuffer sb = new StringBuffer();
Matcher m = Pattern.compile("\\$\\{\\w+\\}").matcher(template);
while (m.find()) {
String param = m.group();
String content = param.substring(2, param.length() - 1);
if (Objects.nonNull(excludes) && excludes.contains(content)) {
continue;
}
Object value = params.get(content);
m.appendReplacement(sb, Matcher.quoteReplacement(value == null ? StringConstant.EMPTY : value.toString()));
}
m.appendTail(sb);
return sb.toString();
}
/**
* 替换最后一个对应字符
*
* @param str 待替换字符串
* @param c 匹配字符
* @param r 特换字符
* @return 替换后字符串
*/
public static String replaceLastChar(String str, char c, char r) {
int lastIdx = str.lastIndexOf(c);
if (lastIdx >= 0) {
StringBuilder sb = new StringBuilder(str);
sb.setCharAt(lastIdx, r);
return sb.toString();
}
return str;
}
/**
* 替换指定字符串的指定区间内字符为指定字符串,字符串只重复一次
* 此方法使用{@link String#codePoints()}完成拆分替换
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @param replacedStr 被替换的字符串
* @return 替换后的字符串
*/
public static String replace(CharSequence str, int startInclude, int endExclude, CharSequence replacedStr) {
if (isEmpty(str)) {
return convert2String(str);
}
final String originalStr = convert2String(str);
int[] strCodePoints = originalStr.codePoints().toArray();
final int strLength = strCodePoints.length;
if (startInclude > strLength) {
return originalStr;
}
if (endExclude > strLength) {
endExclude = strLength;
}
if (startInclude > endExclude) {
// 如果起始位置大于结束位置,不替换
return originalStr;
}
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < startInclude; i++) {
stringBuilder.append(new String(strCodePoints, i, 1));
}
stringBuilder.append(replacedStr);
for (int i = endExclude; i < strLength; i++) {
stringBuilder.append(new String(strCodePoints, i, 1));
}
return stringBuilder.toString();
}
/**
* 格式化文本, {} 表示占位符
* 此方法只是简单将占位符 {} 按照顺序替换为参数
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
* 例:
* 通常使用:format("this is {} for {}", "a", "b") =》 this is a for b
* 转义{}: format("this is \\{} for {}", "a", "b") =》 this is {} for a
* 转义\: format("this is \\\\{} for {}", "a", "b") =》 this is \a for b
*
* @param template 文本模板,被替换的部分用 {} 表示,如果模板为null,返回"null"
* @param params 参数值
* @return 格式化后的文本,如果模板为null,返回""
*/
public static String format(CharSequence template, Object... params) {
if (isEmpty(template)) {
return StringConstant.EMPTY;
}
if (ArrayUtils.isEmpty(params)) {
return template.toString();
}
return StringFormatter.format(template.toString(), params);
}
/**
* 替换指定字符串的指定区间内字符为"*"
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @return 替换后的字符串
*/
public static String hide(CharSequence str, int startInclude, int endExclude) {
int replaceCnt = Math.max(endExclude - startInclude, 1);
replaceCnt = Math.min(replaceCnt, str.length() - startInclude);
StringBuilder replaceStr = new StringBuilder();
for (int i = 0; i < replaceCnt; i++) {
replaceStr.append("*");
}
return replace(str, startInclude, endExclude, replaceStr);
}
/**
* 将 Object 转换为 String
* null或 (不区分大小写), 认定为空
*/
public static String convert2String(Object obj) {
if (obj == null) {
return StringConstant.EMPTY;
}
if (obj instanceof String) {
if (((String) obj).equalsIgnoreCase(StringConstant.NULL) || ((String) obj).equalsIgnoreCase("")) {
return StringConstant.EMPTY;
}
return (String) obj;
} else {
return obj.toString();
}
}
/**
* 调用 convert2String 方法,null会返回{@code null}
*/
public static String convert2StringOrNull(Object obj) {
return Objects.isNull(obj) ? null : convert2String(obj);
}
/**
* 大写第一个字母
*/
public static String upperFirst(String str) {
if (isEmpty(str)) {
return StringConstant.EMPTY;
}
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (!Character.isLetter(c)) {
continue;
}
chars[i] = p_upperChar(c);
break;
}
return String.valueOf(chars);
}
/**
* 小写第一个字母
*/
public static String lowerFirst(String str) {
if (isEmpty(str)) {
return StringConstant.EMPTY;
}
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (!Character.isLetter(c)) {
continue;
}
chars[i] = p_lowerChar(c);
break;
}
return String.valueOf(chars);
}
/**
* 驼峰转下划线
*/
public static String camel2Underline(String str) {
if (isEmpty(str)) {
return StringConstant.EMPTY;
}
StringBuilder buf = new StringBuilder();
for (int i = 0; i < str.length(); ++i) {
char ch = str.charAt(i);
if (ch >= 'A' && ch <= 'Z') {
char ch_ucase = p_lowerChar(ch);
if (i > 0) {
buf.append('_');
}
buf.append(ch_ucase);
} else {
buf.append(ch);
}
}
return buf.toString();
}
/**
* 下划线转驼峰
*/
public static String underline2Camel(String str) {
if (isEmpty(str)) {
return StringConstant.EMPTY;
}
String[] split = str.split("_");
StringBuilder sb = new StringBuilder(str.length());
for (int i = 0; i < split.length; i++) {
String s = split[i];
if (i == 0) {
sb.append(s);
} else {
sb.append(upperFirst(s));
}
}
return sb.toString();
}
/**
* 去掉字符串指定的前缀
*
* @param str 字符串名称
* @param prefix 前缀数组
*/
public static String removePrefix(String str, String[] prefix) {
if (Objects.isNull(str) || str.length() == 0) {
return StringConstant.EMPTY;
} else {
if (null != prefix) {
String[] prefixArray = prefix;
for (int i = 0; i < prefix.length; ++i) {
String pf = prefixArray[i];
if (str.toLowerCase().matches("^" + pf.toLowerCase() + ".*")) {
//截取前缀后面的字符串
return str.substring(pf.length());
}
}
}
return str;
}
}
/**
* 解析成 Integer
*/
@Deprecated
public static Integer parseInt(String str) {
String tmpStr = convert2String(str);
if (tmpStr.equals(StringConstant.EMPTY)) {
return 0;
} else {
int n = 0;
try {
n = (int) Double.parseDouble(tmpStr);
} catch (Exception e) {
return 0;
}
return n;
}
}
/**
* 解析成 Long
*/
@Deprecated
public static Long parseLong(String str) {
String tmpStr = convert2String(str);
if (tmpStr.equals(StringConstant.EMPTY)) {
return 0L;
} else {
long n = 0;
try {
n = Long.parseLong(tmpStr);
} catch (Exception e) {
return 0L;
}
return n;
}
}
/**
* 解析成 Double
*/
@Deprecated
public static Double parseDouble(String str) {
String tmpStr = convert2String(str);
if (tmpStr.equals(StringConstant.EMPTY)) {
return 0.0;
} else {
double n = 0.0;
try {
n = Double.parseDouble(tmpStr);
} catch (Exception e) {
return 0.0;
}
return n;
}
}
/**
* 解析成 Boolean
*/
public static Boolean parseBoolean(String str) {
if (isEmpty(str)) {
return false;
}
return str.equalsIgnoreCase("true")
|| str.equalsIgnoreCase("yes")
|| str.equalsIgnoreCase("success");
}
/**
* 分隔字符串, 之后取第n位子字符串
* 🌰: getSplitAtIdx("a,b,c", ",", 1) -> "b"
*/
public static String getSplitAtIdx(String str, String regex, int idx) {
String string = convert2String(str);
String[] array = string.split(regex);
if (array.length > idx) {
return array[idx];
}
return StringConstant.EMPTY;
}
/**
* 是否有特殊字符
*/
public static boolean hasSpecialChar(String str) {
Pattern p = Pattern.compile(RegexConstant.SPECIAL_CHAR);
Matcher m = p.matcher(str);
return m.find();
}
/**
* 将对象转为字符串
*
*
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
*
* @param obj 对象
* @return 字符串
*/
public static String utf8Str(Object obj) {
return str(obj, StandardCharsets.UTF_8);
}
/**
* 将对象转为字符串
*
*
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
*
* @param obj 对象
* @param charsetName 字符集
* @return 字符串
* @deprecated 请使用 {@link #str(Object, Charset)}
*/
@Deprecated
public static String str(Object obj, String charsetName) {
return str(obj, Charset.forName(charsetName));
}
/**
* 将对象转为字符串
*
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
*
* @param obj 对象
* @param charset 字符集
* @return 字符串
*/
public static String str(Object obj, Charset charset) {
if (null == obj) {
return null;
}
if (obj instanceof String) {
return (String) obj;
} else if (obj instanceof byte[]) {
return str((byte[]) obj, charset);
} else if (obj instanceof Byte[]) {
return str((Byte[]) obj, charset);
} else if (obj instanceof ByteBuffer) {
return str((ByteBuffer) obj, charset);
} else if (ArrayUtils.isArray(obj)) {
return ArrayUtils.toString(obj);
}
return obj.toString();
}
/**
* 将byte数组转为字符串
*
* @param bytes byte数组
* @param charset 字符集
* @return 字符串
*/
public static String str(byte[] bytes, String charset) {
return str(bytes, Charset.forName(charset));
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String str(byte[] data, Charset charset) {
if (data == null) {
return null;
}
if (null == charset) {
return new String(data);
}
return new String(data, charset);
}
/**
* 将Byte数组转为字符串
*
* @param bytes byte数组
* @param charset 字符集
* @return 字符串
*/
public static String str(Byte[] bytes, String charset) {
return str(bytes, Charset.forName(charset));
}
/**
* 解码字节码
*
* @param data 字符串
* @param charset 字符集,如果此字段为空,则解码的结果取决于平台
* @return 解码后的字符串
*/
public static String str(Byte[] data, Charset charset) {
if (data == null) {
return null;
}
byte[] bytes = new byte[data.length];
Byte dataByte;
for (int i = 0; i < data.length; i++) {
dataByte = data[i];
bytes[i] = (null == dataByte) ? -1 : dataByte;
}
return str(bytes, charset);
}
/**
* 将编码的byteBuffer数据转换为字符串
*
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public static String str(ByteBuffer data, String charset) {
if (data == null) {
return null;
}
return str(data, Charset.forName(charset));
}
/**
* 将编码的byteBuffer数据转换为字符串
*
* @param data 数据
* @param charset 字符集,如果为空使用当前系统字符集
* @return 字符串
*/
public static String str(ByteBuffer data, Charset charset) {
if (null == charset) {
charset = Charset.defaultCharset();
}
return charset.decode(data).toString();
}
/**
* 字节长度
*/
public static int bytesLength(String str) {
return convert2String(str).getBytes().length;
}
/**
* base64
*/
public static String base64(String str) {
return Base64.encodeBase64String(convert2String(str).getBytes(StandardCharsets.UTF_8));
}
/**
* md5
*/
public static String md5(String str) {
return hash(str, "MD5");
}
/**
* sah1
*/
public static String sha1(String str) {
return hash(str, "SHA-1");
}
/**
* sha256
*/
public static String sha256(String str) {
return hash(str, "SHA-256");
}
/**
* sha512
*/
public static String sha512(String str) {
return hash(str, "SHA-512");
}
/**
* hash 值
*
* @param str 字符串
* @param type 类型: (🌰: MD5, SHA-1, ...)
*/
public static String hash(String str, String type) {
try {
MessageDigest digest = MessageDigest.getInstance(type);
return Hex.encodeHexString(digest.digest(convert2String(str).getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return StringConstant.EMPTY;
}
public static Boolean containsAnyChar(String str, char... chars) {
if (!isEmpty(str)) {
int len = str.length();
for (int i = 0; i < len; i++) {
if (ArrayUtils.contains(chars, str.charAt(i))) {
return true;
}
}
}
return false;
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param testStrs 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public static boolean containsAny(CharSequence str, CharSequence... testStrs) {
return null != getContainsStr(str, testStrs);
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串,如果包含返回找到的第一个字符串
*
* @param str 指定字符串
* @param testStrs 需要检查的字符串数组
* @return 被包含的第一个字符串
*/
public static String getContainsStr(CharSequence str, CharSequence... testStrs) {
if (isEmpty(str) || ArrayUtils.isEmpty(testStrs)) {
return null;
}
for (CharSequence checkStr : testStrs) {
if (null != checkStr && str.toString().contains(checkStr)) {
return checkStr.toString();
}
}
return null;
}
/**
* 字符串是否包含该正则
*
* @param str 待匹配字符串
* @param regex 正则表达式
*/
public static Boolean hasRegex(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(str).find();
}
/**
* 字符串是否只包含该正则
*
* @param str 待匹配字符串
* @param regex 正则表达式
*/
public static Boolean onlyRegex(String str, String regex) {
return Pattern.matches(regex, str);
}
/**
* 查找满足正则匹配条件的第一个字符串
*
* @param str 待匹配字符串
* @param regex 正则表达式
*/
public static String findRegexFirst(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
if (matcher.find()) {
return matcher.group();
}
return null;
}
/**
* 查找满足正则匹配条件的所有字符串
*
* @param str 待匹配字符串
* @param regex 正则表达式
*/
public static List findRegexList(String str, String regex) {
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
List list = new ArrayList<>();
while (matcher.find()) {
list.add(matcher.group());
}
return list;
}
/**
* 获取字符串中指定字符串数量
*
* @param str 待匹配字符串
* @param symbol 指定字符串
*/
public static int specifiedSymbolCount(String str, String symbol) {
return (str.length() - str.replace(symbol, StringConstant.EMPTY).length()) / symbol.length();
}
/**
* 是否以指定字符串开头
* 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
*
* @param str 待匹配字符串
* @param prefix 开头
* @param isIgnoreCase 是否忽略大小写
* @param isIgnoreEquals 是否忽略字符串相等的情况
*/
public static boolean startWith(CharSequence str, CharSequence prefix, boolean isIgnoreCase, boolean isIgnoreEquals) {
if (Objects.isNull(str) || Objects.isNull(prefix)) {
return !isIgnoreEquals;
}
String s = str.toString();
String p = prefix.toString();
boolean isStartWith = s.regionMatches(isIgnoreCase, 0, p, 0, prefix.length());
if (isStartWith) {
return !isIgnoreEquals || s.equalsIgnoreCase(p);
}
return false;
}
/**
* 是否以指定字符串开头,忽略大小写
*
* @param str 被监测字符串
* @param prefix 开头字符串
*/
public static boolean startWithIgnoreCase(CharSequence str, CharSequence prefix) {
return startWith(str, prefix, true, false);
}
private static char p_upperChar(char c) {
if (c >= 97) {
c -= 32;
}
return c;
}
private static char p_lowerChar(char c) {
if (c < 97) {
c += 32;
}
return c;
}
}