|
@@ -124,6 +124,11 @@ public final class StringUtils {
|
|
|
*/
|
|
|
public static final String NUMBER_REGEX = "[\\+-]?(\\.?[0-9]+|[0-9]+\\.?[0-9]+|[0-9]+\\.?)";
|
|
|
|
|
|
+ /**
|
|
|
+ * IP正则表达式
|
|
|
+ */
|
|
|
+ public static final String IP_REGEX = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}(/[1-9]{1,2})?";
|
|
|
+
|
|
|
/**
|
|
|
* URL正则表达式
|
|
|
*/
|
|
@@ -140,6 +145,11 @@ public final class StringUtils {
|
|
|
*/
|
|
|
public static final String EMAIL_REGEX = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
|
|
|
|
|
|
+ /**
|
|
|
+ * 版本号正则表达式
|
|
|
+ */
|
|
|
+ public static final String VERSION_REGEX = "[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}";
|
|
|
+
|
|
|
/**
|
|
|
* 特殊字符正则表达式
|
|
|
*/
|
|
@@ -184,16 +194,6 @@ public final class StringUtils {
|
|
|
private StringUtils() {
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 去掉字符串左右空格
|
|
|
- *
|
|
|
- * @param original 原始字符串
|
|
|
- * @return 字符串
|
|
|
- */
|
|
|
- public static String trim(String original) {
|
|
|
- return original == null ? null : original.trim();
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 判断对象是否为空
|
|
|
*
|
|
@@ -201,7 +201,7 @@ public final class StringUtils {
|
|
|
* @return true/false
|
|
|
*/
|
|
|
public static boolean isEmpty(Object object) {
|
|
|
- return object == null || EMPTY.equals(object);
|
|
|
+ return object == null || (object instanceof CharSequence && ((CharSequence) object).length() == 0);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -383,6 +383,17 @@ public final class StringUtils {
|
|
|
return notEmpty(source) && getPattern(LETTER_REGEX).matcher(source).matches();
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 判断字符串是否是IP
|
|
|
+ *
|
|
|
+ * @param source 字符串
|
|
|
+ * @param <T> 字符串类型
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static <T extends CharSequence> boolean isIp(T source) {
|
|
|
+ return notEmpty(source) && getPattern(IP_REGEX).matcher(source).matches();
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 判断字符串是否是URL
|
|
|
*
|
|
@@ -417,7 +428,18 @@ public final class StringUtils {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 判断是否是特殊字符
|
|
|
+ * 判断字符串是否是版本号
|
|
|
+ *
|
|
|
+ * @param source 字符串
|
|
|
+ * @param <T> 字符串类型
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static <T extends CharSequence> boolean isVersion(T source) {
|
|
|
+ return notEmpty(source) && getPattern(VERSION_REGEX).matcher(source).matches();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断字符串是否是特殊字符
|
|
|
*
|
|
|
* @param source 字符串
|
|
|
* @param <T> 字符串类型
|
|
@@ -581,9 +603,13 @@ public final class StringUtils {
|
|
|
* @param index 开始下标(负数标识从字符串末尾开始)
|
|
|
* @return 子字符串
|
|
|
*/
|
|
|
- public static String substring(String original, int index) {
|
|
|
- return isEmpty(original) ? original :
|
|
|
- index < 0 ? original.substring(original.length() + index) : original.substring(index);
|
|
|
+ public static String substring(CharSequence original, int index) {
|
|
|
+ if (isEmpty(original)) {
|
|
|
+ return original == null ? null : EMPTY;
|
|
|
+ } else if (index < 0) {
|
|
|
+ return original.subSequence(original.length() + index, original.length()).toString();
|
|
|
+ }
|
|
|
+ return original.subSequence(index, original.length()).toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -594,14 +620,76 @@ public final class StringUtils {
|
|
|
* @param length 截取长度
|
|
|
* @return 子字符串
|
|
|
*/
|
|
|
- public static String substring(String original, int index, int length) {
|
|
|
+ public static String substring(CharSequence original, int index, int length) {
|
|
|
AssertUtils.check(length > -1, () -> "length must be greater than -1");
|
|
|
if (isEmpty(original)) {
|
|
|
- return original;
|
|
|
+ return original == null ? null : EMPTY;
|
|
|
} else if (index < 0) {
|
|
|
index += original.length();
|
|
|
}
|
|
|
- return original.substring(index, Math.min(original.length(), index + length));
|
|
|
+ return original.subSequence(index, Math.min(original.length(), index + length)).toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 去掉字符串左右空格
|
|
|
+ *
|
|
|
+ * @param original 原始字符串
|
|
|
+ * @return 字符串
|
|
|
+ */
|
|
|
+ public static String trim(CharSequence original) {
|
|
|
+ if (isEmpty(original)) {
|
|
|
+ return original == null ? null : EMPTY;
|
|
|
+ } else if (original instanceof String) {
|
|
|
+ return ((String) original).trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ int i = 0, size = original.length();
|
|
|
+ while (i < size && original.charAt(i) <= ' ') {
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ while (i < size && original.charAt(size - 1) <= ' ') {
|
|
|
+ size--;
|
|
|
+ }
|
|
|
+ if (i > 0 || size < original.length()) {
|
|
|
+ return original.subSequence(i, size).toString();
|
|
|
+ }
|
|
|
+ return original.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 去掉字符串右边空格
|
|
|
+ *
|
|
|
+ * @param original 原始字符串
|
|
|
+ * @return 字符串
|
|
|
+ */
|
|
|
+ public static String rtrim(CharSequence original) {
|
|
|
+ if (isEmpty(original)) {
|
|
|
+ return original == null ? null : EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
+ int size = original.length();
|
|
|
+ while (size > 0 && original.charAt(size - 1) <= ' ') {
|
|
|
+ size--;
|
|
|
+ }
|
|
|
+ return size < original.length() ? original.subSequence(0, size).toString() : original.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 去掉字符串左边空格
|
|
|
+ *
|
|
|
+ * @param original 原始字符串
|
|
|
+ * @return 字符串
|
|
|
+ */
|
|
|
+ public static String ltrim(CharSequence original) {
|
|
|
+ if (isEmpty(original)) {
|
|
|
+ return original == null ? null : EMPTY;
|
|
|
+ }
|
|
|
+
|
|
|
+ int i = 0, size = original.length();
|
|
|
+ while (i < size && original.charAt(i) <= ' ') {
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return i > 0 ? original.subSequence(i, size).toString() : original.toString();
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -611,7 +699,7 @@ public final class StringUtils {
|
|
|
* @param length 字符串总长度
|
|
|
* @return 对齐后的字符串
|
|
|
*/
|
|
|
- public static String ljust(String original, int length) {
|
|
|
+ public static String ljust(CharSequence original, int length) {
|
|
|
return ljust(original, length, ' ');
|
|
|
}
|
|
|
|
|
@@ -623,7 +711,7 @@ public final class StringUtils {
|
|
|
* @param c 补齐字符
|
|
|
* @return 对齐后的字符串
|
|
|
*/
|
|
|
- public static String ljust(String original, int length, char c) {
|
|
|
+ public static String ljust(CharSequence original, int length, char c) {
|
|
|
return just(original, length, c, false);
|
|
|
}
|
|
|
|
|
@@ -634,7 +722,7 @@ public final class StringUtils {
|
|
|
* @param length 字符串总长度
|
|
|
* @return 对齐后的字符串
|
|
|
*/
|
|
|
- public static String rjust(String original, int length) {
|
|
|
+ public static String rjust(CharSequence original, int length) {
|
|
|
return rjust(original, length, ' ');
|
|
|
}
|
|
|
|
|
@@ -646,7 +734,7 @@ public final class StringUtils {
|
|
|
* @param c 补齐字符
|
|
|
* @return 对齐后的字符串
|
|
|
*/
|
|
|
- public static String rjust(String original, int length, char c) {
|
|
|
+ public static String rjust(CharSequence original, int length, char c) {
|
|
|
return just(original, length, c, true);
|
|
|
}
|
|
|
|
|
@@ -659,10 +747,10 @@ public final class StringUtils {
|
|
|
* @param right 是否是右对齐
|
|
|
* @return 对齐后的字符串
|
|
|
*/
|
|
|
- private static String just(String original, int length, char c, boolean right) {
|
|
|
+ private static String just(CharSequence original, int length, char c, boolean right) {
|
|
|
AssertUtils.check(length > -1, () -> "length must be greater than -1");
|
|
|
if (length == 0 || (notEmpty(original) && length <= original.length())) {
|
|
|
- return original;
|
|
|
+ return ObjectUtils.ifNull(original, Object::toString);
|
|
|
}
|
|
|
StringBuilder builder = new StringBuilder();
|
|
|
|
|
@@ -670,7 +758,7 @@ public final class StringUtils {
|
|
|
if (!right && notEmpty(original)) {
|
|
|
builder.append(original);
|
|
|
}
|
|
|
- for (int i = 0, size = length - ObjectUtils.ifNull(original, String::length, () -> 0); i < size; i++) {
|
|
|
+ for (int i = 0, size = length - ObjectUtils.ifNull(original, CharSequence::length, () -> 0); i < size; i++) {
|
|
|
builder.append(c);
|
|
|
}
|
|
|
|
|
@@ -1461,4 +1549,112 @@ public final class StringUtils {
|
|
|
crc.update(source.getBytes());
|
|
|
return crc.getValue();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断字符串是否匹配真实前缀(忽略空格)
|
|
|
+ *
|
|
|
+ * @param sequence 字符串
|
|
|
+ * @param prefix 匹配前缀
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static boolean isRealPrefix(CharSequence sequence, @NonNull String prefix) {
|
|
|
+ if (sequence == null) {
|
|
|
+ return false;
|
|
|
+ } else if (isBlank(prefix)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ int i = 0, size = sequence.length();
|
|
|
+ while (i < size && sequence.charAt(i) <= ' ') {
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size - i < prefix.length()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int k = 0, c = prefix.length(); k < c; k++) {
|
|
|
+ if (sequence.charAt(i + k) != prefix.charAt(k)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断字符串是否包含真实前缀(忽略空格)
|
|
|
+ *
|
|
|
+ * @param sequence 字符串
|
|
|
+ * @param prefixes 前缀数组
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static boolean hasRealPrefix(CharSequence sequence, @NonNull String... prefixes) {
|
|
|
+ if (sequence != null && ObjectUtils.notEmpty(prefixes)) {
|
|
|
+ for (String prefix : prefixes) {
|
|
|
+ if (isRealPrefix(sequence, prefix)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断字符串是否匹配真实后缀(忽略空格)
|
|
|
+ *
|
|
|
+ * @param sequence 字符串
|
|
|
+ * @param suffix 匹配后缀
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static boolean isRealSuffix(CharSequence sequence, @NonNull String suffix) {
|
|
|
+ if (sequence == null) {
|
|
|
+ return false;
|
|
|
+ } else if (isBlank(suffix)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ int size = sequence.length();
|
|
|
+ while (size > 0 && sequence.charAt(size - 1) <= ' ') {
|
|
|
+ size--;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (size < suffix.length()) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = size - 1, k = suffix.length() - 1; k >= 0; k--, i--) {
|
|
|
+ if (sequence.charAt(i) != suffix.charAt(k)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断字符串是否包含真实后缀(忽略空格)
|
|
|
+ *
|
|
|
+ * @param sequence 字符串
|
|
|
+ * @param suffixes 后缀数组
|
|
|
+ * @return true/false
|
|
|
+ */
|
|
|
+ public static boolean hasRealSuffix(CharSequence sequence, @NonNull String... suffixes) {
|
|
|
+ if (sequence != null && ObjectUtils.notEmpty(suffixes)) {
|
|
|
+ for (String suffix : suffixes) {
|
|
|
+ if (isRealSuffix(sequence, suffix)) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将对象转换成字符串
|
|
|
+ *
|
|
|
+ * @param object 对象实例
|
|
|
+ * @return 字符串
|
|
|
+ */
|
|
|
+ public static String toString(Object object) {
|
|
|
+ return object == null ? null : object.toString();
|
|
|
+ }
|
|
|
}
|