字符串是否为空白,空白的定义如下:
+ *例:
+ *注意:该方法与 {@link #isEmpty(CharSequence)} 的区别是: + * 该方法会校验空白字符,且性能相对于 {@link #isEmpty(CharSequence)} 略慢。
+ *建议:
+ *字符串是否为非空白,非空白的定义如下:
+ *例:
+ *注意:该方法与 {@link #isNotEmpty(CharSequence)} 的区别是: + * 该方法会校验空白字符,且性能相对于 {@link #isNotEmpty(CharSequence)} 略慢。
+ *建议:仅对于客户端(或第三方接口)传入的参数使用该方法。
+ * + * @param str 被检测的字符串 + * @return 是否为非空 + * @see #isBlank(CharSequence) + */ + public static boolean isNotBlank(CharSequence str) { + return false == isBlank(str); + } + + /** + *指定字符串数组中,是否包含空字符串。
+ *如果指定的字符串数组的长度为 0,或者其中的任意一个元素是空字符串,则返回 true。
+ *例:
+ *注意:该方法与 {@link #isAllBlank(CharSequence...)} 的区别在于:
+ *指定字符串数组中的元素,是否全部为空字符串。
+ *如果指定的字符串数组的长度为 0,或者所有元素都是空字符串,则返回 true。
+ *例:
+ *注意:该方法与 {@link #hasBlank(CharSequence...)} 的区别在于:
+ *字符串是否为空,空的定义如下:
+ *例:
+ *注意:该方法与 {@link #isBlank(CharSequence)} 的区别是:该方法不校验空白字符。
+ *建议:
+ *字符串是否为非空白,非空白的定义如下:
+ *例:
+ *注意:该方法与 {@link #isNotBlank(CharSequence)} 的区别是:该方法不校验空白字符。
+ *建议:该方法建议用于工具类或任何可以预期的方法参数的校验中。
+ * + * @param str 被检测的字符串 + * @return 是否为非空 + * @see #isEmpty(CharSequence) + */ + public static boolean isNotEmpty(CharSequence str) { + return false == isEmpty(str); + } + + /** + * 当给定字符串为null时,转换为Empty + * + * @param str 被检查的字符串 + * @return 原字符串或者空串 + * @see #nullToEmpty(CharSequence) + * @since 4.6.3 + */ + public static String emptyIfNull(CharSequence str) { + return nullToEmpty(str); + } + + /** + * 当给定字符串为null时,转换为Empty + * + * @param str 被转换的字符串 + * @return 转换后的字符串 + */ + public static String nullToEmpty(CharSequence str) { + return nullToDefault(str, EMPTY); + } + + /** + * 如果字符串是 {@code null},则返回指定默认字符串,否则返回字符串本身。 + * + *
+ * nullToDefault(null, "default") = "default"
+ * nullToDefault("", "default") = ""
+ * nullToDefault(" ", "default") = " "
+ * nullToDefault("bat", "default") = "bat"
+ *
+ *
+ * @param str 要转换的字符串
+ * @param defaultStr 默认字符串
+ * @return 字符串本身或指定的默认字符串
+ */
+ public static String nullToDefault(CharSequence str, String defaultStr) {
+ return (str == null) ? defaultStr : str.toString();
+ }
+
+ /**
+ * 如果字符串是{@code null}或者"",则返回指定默认字符串,否则返回字符串本身。
+ *
+ *
+ * emptyToDefault(null, "default") = "default"
+ * emptyToDefault("", "default") = "default"
+ * emptyToDefault(" ", "default") = " "
+ * emptyToDefault("bat", "default") = "bat"
+ *
+ *
+ * @param str 要转换的字符串
+ * @param defaultStr 默认字符串
+ * @return 字符串本身或指定的默认字符串
+ * @since 4.1.0
+ */
+ public static String emptyToDefault(CharSequence str, String defaultStr) {
+ return isEmpty(str) ? defaultStr : str.toString();
+ }
+
+ /**
+ * 如果字符串是{@code null}或者""或者空白,则返回指定默认字符串,否则返回字符串本身。
+ *
+ *
+ * emptyToDefault(null, "default") = "default"
+ * emptyToDefault("", "default") = "default"
+ * emptyToDefault(" ", "default") = "default"
+ * emptyToDefault("bat", "default") = "bat"
+ *
+ *
+ * @param str 要转换的字符串
+ * @param defaultStr 默认字符串
+ * @return 字符串本身或指定的默认字符串
+ * @since 4.1.0
+ */
+ public static String blankToDefault(CharSequence str, String defaultStr) {
+ return isBlank(str) ? defaultStr : str.toString();
+ }
+
+ /**
+ * 当给定字符串为空字符串时,转换为{@code null}
+ *
+ * @param str 被转换的字符串
+ * @return 转换后的字符串
+ */
+ public static String emptyToNull(CharSequence str) {
+ return isEmpty(str) ? null : str.toString();
+ }
+
+ /**
+ * 是否包含空字符串。
+ *如果指定的字符串数组的长度为 0,或者其中的任意一个元素是空字符串,则返回 true。
+ *例:
+ *注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:
+ *指定字符串数组中的元素,是否全部为空字符串。
+ *如果指定的字符串数组的长度为 0,或者所有元素都是空字符串,则返回 true。
+ *例:
+ *注意:该方法与 {@link #hasEmpty(CharSequence...)} 的区别在于:
+ *指定字符串数组中的元素,是否都不为空字符串。
+ *如果指定的字符串数组的长度不为 0,或者所有元素都不是空字符串,则返回 true。
+ *例:
+ *注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:
+ *+ * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 + * + *
+ * trim(null) = null
+ * trim("") = ""
+ * trim(" ") = ""
+ * trim("abc") = "abc"
+ * trim(" abc ") = "abc"
+ *
+ *
+ * @param str 要处理的字符串
+ * @return 除去头尾空白的字符串,如果原字串为{@code null},则返回{@code null}
+ */
+ public static String trim(CharSequence str) {
+ return (null == str) ? null : trim(str, 0);
+ }
+
+ /**
+ * 除去字符串头尾部的空白,如果字符串是{@code null},返回{@code ""}。
+ *
+ *
+ * StrUtil.trimToEmpty(null) = ""
+ * StrUtil.trimToEmpty("") = ""
+ * StrUtil.trimToEmpty(" ") = ""
+ * StrUtil.trimToEmpty("abc") = "abc"
+ * StrUtil.trimToEmpty(" abc ") = "abc"
+ *
+ *
+ * @param str 字符串
+ * @return 去除两边空白符后的字符串, 如果为null返回""
+ * @since 3.1.1
+ */
+ public static String trimToEmpty(CharSequence str) {
+ return str == null ? EMPTY : trim(str);
+ }
+
+ /**
+ * 除去字符串头尾部的空白,如果字符串是{@code null}或者"",返回{@code null}。
+ *
+ *
+ * StrUtil.trimToNull(null) = null
+ * StrUtil.trimToNull("") = null
+ * StrUtil.trimToNull(" ") = null
+ * StrUtil.trimToNull("abc") = "abc"
+ * StrUtil.trimToEmpty(" abc ") = "abc"
+ *
+ *
+ * @param str 字符串
+ * @return 去除两边空白符后的字符串, 如果为空返回null
+ * @since 3.2.1
+ */
+ public static String trimToNull(CharSequence str) {
+ final String trimStr = trim(str);
+ return EMPTY.equals(trimStr) ? null : trimStr;
+ }
+
+ /**
+ * 除去字符串头部的空白,如果字符串是{@code null},则返回{@code null}。
+ *
+ * + * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 + * + *
+ * trimStart(null) = null
+ * trimStart("") = ""
+ * trimStart("abc") = "abc"
+ * trimStart(" abc") = "abc"
+ * trimStart("abc ") = "abc "
+ * trimStart(" abc ") = "abc "
+ *
+ *
+ * @param str 要处理的字符串
+ * @return 除去空白的字符串,如果原字串为{@code null}或结果字符串为{@code ""},则返回 {@code null}
+ */
+ public static String trimStart(CharSequence str) {
+ return trim(str, -1);
+ }
+
+ /**
+ * 除去字符串尾部的空白,如果字符串是{@code null},则返回{@code null}。
+ *
+ * + * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 + * + *
+ * trimEnd(null) = null
+ * trimEnd("") = ""
+ * trimEnd("abc") = "abc"
+ * trimEnd(" abc") = " abc"
+ * trimEnd("abc ") = "abc"
+ * trimEnd(" abc ") = " abc"
+ *
+ *
+ * @param str 要处理的字符串
+ * @return 除去空白的字符串,如果原字串为{@code null}或结果字符串为{@code ""},则返回 {@code null}
+ */
+ public static String trimEnd(CharSequence str) {
+ return trim(str, 1);
+ }
+
+ /**
+ * 除去字符串头尾部的空白符,如果字符串是{@code null},依然返回{@code null}。
+ *
+ * @param str 要处理的字符串
+ * @param mode {@code -1}表示trimStart,{@code 0}表示trim全部, {@code 1}表示trimEnd
+ * @return 除去指定字符后的的字符串,如果原字串为{@code null},则返回{@code null}
+ */
+ public static String trim(CharSequence str, int mode) {
+ String result;
+ if (str == null) {
+ result = null;
+ } else {
+ int length = str.length();
+ int start = 0;
+ int end = length;// 扫描字符串头部
+ if (mode <= 0) {
+ while ((start < end) && (CharUtil.isBlankChar(str.charAt(start)))) {
+ start++;
+ }
+ }// 扫描字符串尾部
+ if (mode >= 0) {
+ while ((start < end) && (CharUtil.isBlankChar(str.charAt(end - 1)))) {
+ end--;
+ }
+ }
+ if ((start > 0) || (end < length)) {
+ result = str.toString().substring(start, end);
+ } else {
+ result = str.toString();
+ }
+ }
+
+ return result;
+ }
+
+ // ------------------------------------------------------------------------ startWith
+
+ /**
+ * 字符串是否以给定字符开始
+ *
+ * @param str 字符串
+ * @param c 字符
+ * @return 是否开始
+ */
+ public static boolean startWith(CharSequence str, char c) {
+ if (isEmpty(str)) {
+ return false;
+ }
+ return c == str.charAt(0);
+ }
+
+ /**
+ * 是否以指定字符串开头
+ * StrUtil.indexOfIgnoreCase(null, *, *) = -1
+ * StrUtil.indexOfIgnoreCase(*, null, *) = -1
+ * StrUtil.indexOfIgnoreCase("", "", 0) = 0
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
+ * StrUtil.indexOfIgnoreCase("abc", "", 9) = -1
+ *
+ *
+ * @param str 字符串
+ * @param searchStr 需要查找位置的字符串
+ * @return 位置
+ * @since 3.2.1
+ */
+ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+ return indexOfIgnoreCase(str, searchStr, 0);
+ }
+
+ /**
+ * 指定范围内查找字符串
+ *
+ *
+ * StrUtil.indexOfIgnoreCase(null, *, *) = -1
+ * StrUtil.indexOfIgnoreCase(*, null, *) = -1
+ * StrUtil.indexOfIgnoreCase("", "", 0) = 0
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
+ * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
+ * StrUtil.indexOfIgnoreCase("abc", "", 9) = -1
+ *
+ *
+ * @param str 字符串
+ * @param searchStr 需要查找位置的字符串
+ * @param fromIndex 起始位置
+ * @return 位置
+ * @since 3.2.1
+ */
+ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
+ return indexOf(str, searchStr, fromIndex, true);
+ }
+
+ /**
+ * 指定范围内查找字符串
+ *
+ * @param str 字符串
+ * @param searchStr 需要查找位置的字符串
+ * @param fromIndex 起始位置
+ * @param ignoreCase 是否忽略大小写
+ * @return 位置
+ * @since 3.2.1
+ */
+ public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) {
+ if (str == null || searchStr == null) {
+ return INDEX_NOT_FOUND;
+ }
+ if (fromIndex < 0) {
+ fromIndex = 0;
+ }
+
+ final int endLimit = str.length() - searchStr.length() + 1;
+ if (fromIndex > endLimit) {
+ return INDEX_NOT_FOUND;
+ }
+ if (searchStr.length() == 0) {
+ return fromIndex;
+ }
+
+ if (false == ignoreCase) {
+ // 不忽略大小写调用JDK方法
+ return str.toString().indexOf(searchStr.toString(), fromIndex);
+ }
+
+ for (int i = fromIndex; i < endLimit; i++) {
+ if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
+ return i;
+ }
+ }
+ return INDEX_NOT_FOUND;
+ }
+
+ /**
+ * 指定范围内查找字符串,忽略大小写
+ *
+ * @param str 字符串
+ * @param searchStr 需要查找位置的字符串
+ * @return 位置
+ * @since 3.2.1
+ */
+ public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
+ return lastIndexOfIgnoreCase(str, searchStr, str.length());
+ }
+
+ /**
+ * 指定范围内查找字符串,忽略大小写
+ * 如果 str=null 或 searchStr=null 或 ordinal≥0 则返回-1
+ * 此方法来自:Apache-Commons-Lang
+ *
+ * 例子(*代表任意字符): + * + *
+ * StrUtil.ordinalIndexOf(null, *, *) = -1
+ * StrUtil.ordinalIndexOf(*, null, *) = -1
+ * StrUtil.ordinalIndexOf("", "", *) = 0
+ * StrUtil.ordinalIndexOf("aabaabaa", "a", 1) = 0
+ * StrUtil.ordinalIndexOf("aabaabaa", "a", 2) = 1
+ * StrUtil.ordinalIndexOf("aabaabaa", "b", 1) = 2
+ * StrUtil.ordinalIndexOf("aabaabaa", "b", 2) = 5
+ * StrUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
+ * StrUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
+ * StrUtil.ordinalIndexOf("aabaabaa", "", 1) = 0
+ * StrUtil.ordinalIndexOf("aabaabaa", "", 2) = 0
+ *
+ *
+ * @param str 被检查的字符串,可以为null
+ * @param searchStr 被查找的字符串,可以为null
+ * @param ordinal 第几次出现的位置
+ * @return 查找到的位置
+ * @since 3.2.3
+ */
+ public static int ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) {
+ if (str == null || searchStr == null || ordinal <= 0) {
+ return INDEX_NOT_FOUND;
+ }
+ if (searchStr.length() == 0) {
+ return 0;
+ }
+ int found = 0;
+ int index = INDEX_NOT_FOUND;
+ do {
+ index = indexOf(str, searchStr, index + 1, false);
+ if (index < 0) {
+ return index;
+ }
+ found++;
+ } while (found < ordinal);
+ return index;
+ }
+
+ // ------------------------------------------------------------------------ remove
+
+ /**
+ * 移除字符串中所有给定字符串+ * 1. \r + * 1. \n + *+ * + * @param str 字符串 + * @return 处理后的字符串 + * @since 4.2.2 + */ + public static String removeAllLineBreaks(CharSequence str) { + return removeAll(str, CharUtil.CR, CharUtil.LF); + } + + /** + * 去掉首部指定长度的字符串并将剩余字符串首字母小写
+ * StrUtil.subSufByLength("abcde", 3) = "cde"
+ * StrUtil.subSufByLength("abcde", 0) = ""
+ * StrUtil.subSufByLength("abcde", -5) = ""
+ * StrUtil.subSufByLength("abcde", -1) = ""
+ * StrUtil.subSufByLength("abcde", 5) = "abcde"
+ * StrUtil.subSufByLength("abcde", 10) = "abcde"
+ * StrUtil.subSufByLength(null, 3) = null
+ *
+ *
+ * @param string 字符串
+ * @param length 切割长度
+ * @return 切割后后剩余的后半部分字符串
+ * @since 4.0.1
+ */
+ public static String subSufByLength(CharSequence string, int length) {
+ if (isEmpty(string)) {
+ return null;
+ }
+ if (length <= 0) {
+ return EMPTY;
+ }
+ return sub(string, -length, string.length());
+ }
+
+ /**
+ * 截取字符串,从指定位置开始,截取指定长度的字符串
+ * StrUtil.subBefore(null, *, false) = null
+ * StrUtil.subBefore("", *, false) = ""
+ * StrUtil.subBefore("abc", "a", false) = ""
+ * StrUtil.subBefore("abcba", "b", false) = "a"
+ * StrUtil.subBefore("abc", "c", false) = "ab"
+ * StrUtil.subBefore("abc", "d", false) = "abc"
+ * StrUtil.subBefore("abc", "", false) = ""
+ * StrUtil.subBefore("abc", null, false) = "abc"
+ *
+ *
+ * @param string 被查找的字符串
+ * @param separator 分隔字符串(不包括)
+ * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
+ * @return 切割后的字符串
+ * @since 3.1.1
+ */
+ public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+ if (isEmpty(string) || separator == null) {
+ return null == string ? null : string.toString();
+ }
+
+ final String str = string.toString();
+ final String sep = separator.toString();
+ if (sep.isEmpty()) {
+ return EMPTY;
+ }
+ final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+ if (INDEX_NOT_FOUND == pos) {
+ return str;
+ }
+ if (0 == pos) {
+ return EMPTY;
+ }
+ return str.substring(0, pos);
+ }
+
+ /**
+ * 截取分隔字符串之前的字符串,不包括分隔字符串
+ * StrUtil.subBefore(null, *, false) = null
+ * StrUtil.subBefore("", *, false) = ""
+ * StrUtil.subBefore("abc", 'a', false) = ""
+ * StrUtil.subBefore("abcba", 'b', false) = "a"
+ * StrUtil.subBefore("abc", 'c', false) = "ab"
+ * StrUtil.subBefore("abc", 'd', false) = "abc"
+ *
+ *
+ * @param string 被查找的字符串
+ * @param separator 分隔字符串(不包括)
+ * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
+ * @return 切割后的字符串
+ * @since 4.1.15
+ */
+ public static String subBefore(CharSequence string, char separator, boolean isLastSeparator) {
+ if (isEmpty(string)) {
+ return null == string ? null : EMPTY;
+ }
+
+ final String str = string.toString();
+ final int pos = isLastSeparator ? str.lastIndexOf(separator) : str.indexOf(separator);
+ if (INDEX_NOT_FOUND == pos) {
+ return str;
+ }
+ if (0 == pos) {
+ return EMPTY;
+ }
+ return str.substring(0, pos);
+ }
+
+ /**
+ * 截取分隔字符串之后的字符串,不包括分隔字符串
+ * StrUtil.subAfter(null, *, false) = null
+ * StrUtil.subAfter("", *, false) = ""
+ * StrUtil.subAfter(*, null, false) = ""
+ * StrUtil.subAfter("abc", "a", false) = "bc"
+ * StrUtil.subAfter("abcba", "b", false) = "cba"
+ * StrUtil.subAfter("abc", "c", false) = ""
+ * StrUtil.subAfter("abc", "d", false) = ""
+ * StrUtil.subAfter("abc", "", false) = "abc"
+ *
+ *
+ * @param string 被查找的字符串
+ * @param separator 分隔字符串(不包括)
+ * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
+ * @return 切割后的字符串
+ * @since 3.1.1
+ */
+ public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) {
+ if (isEmpty(string)) {
+ return null == string ? null : EMPTY;
+ }
+ if (separator == null) {
+ return EMPTY;
+ }
+ final String str = string.toString();
+ final String sep = separator.toString();
+ final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
+ if (INDEX_NOT_FOUND == pos || (string.length() - 1) == pos) {
+ return EMPTY;
+ }
+ return str.substring(pos + separator.length());
+ }
+
+ /**
+ * 截取分隔字符串之后的字符串,不包括分隔字符串
+ * StrUtil.subAfter(null, *, false) = null
+ * StrUtil.subAfter("", *, false) = ""
+ * StrUtil.subAfter("abc", 'a', false) = "bc"
+ * StrUtil.subAfter("abcba", 'b', false) = "cba"
+ * StrUtil.subAfter("abc", 'c', false) = ""
+ * StrUtil.subAfter("abc", 'd', false) = ""
+ *
+ *
+ * @param string 被查找的字符串
+ * @param separator 分隔字符串(不包括)
+ * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
+ * @return 切割后的字符串
+ * @since 4.1.15
+ */
+ public static String subAfter(CharSequence string, char separator, boolean isLastSeparator) {
+ if (isEmpty(string)) {
+ return null == string ? null : EMPTY;
+ }
+ final String str = string.toString();
+ final int pos = isLastSeparator ? str.lastIndexOf(separator) : str.indexOf(separator);
+ if (INDEX_NOT_FOUND == pos) {
+ return EMPTY;
+ }
+ return str.substring(pos + 1);
+ }
+
+ /**
+ * 截取指定字符串中间部分,不包括标识字符串+ * 栗子: + * + *
+ * StrUtil.subBetween("wx[b]yz", "[", "]") = "b"
+ * StrUtil.subBetween(null, *, *) = null
+ * StrUtil.subBetween(*, null, *) = null
+ * StrUtil.subBetween(*, *, null) = null
+ * StrUtil.subBetween("", "", "") = ""
+ * StrUtil.subBetween("", "", "]") = null
+ * StrUtil.subBetween("", "[", "]") = null
+ * StrUtil.subBetween("yabcz", "", "") = ""
+ * StrUtil.subBetween("yabcz", "y", "z") = "abc"
+ * StrUtil.subBetween("yabczyabcz", "y", "z") = "abc"
+ *
+ *
+ * @param str 被切割的字符串
+ * @param before 截取开始的字符串标识
+ * @param after 截取到的字符串标识
+ * @return 截取后的字符串
+ * @since 3.1.1
+ */
+ public static String subBetween(CharSequence str, CharSequence before, CharSequence after) {
+ if (str == null || before == null || after == null) {
+ return null;
+ }
+
+ final String str2 = str.toString();
+ final String before2 = before.toString();
+ final String after2 = after.toString();
+
+ final int start = str2.indexOf(before2);
+ if (start != INDEX_NOT_FOUND) {
+ final int end = str2.indexOf(after2, start + before2.length());
+ if (end != INDEX_NOT_FOUND) {
+ return str2.substring(start + before2.length(), end);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 截取指定字符串中间部分,不包括标识字符串+ * 栗子: + * + *
+ * StrUtil.subBetween(null, *) = null
+ * StrUtil.subBetween("", "") = ""
+ * StrUtil.subBetween("", "tag") = null
+ * StrUtil.subBetween("tagabctag", null) = null
+ * StrUtil.subBetween("tagabctag", "") = ""
+ * StrUtil.subBetween("tagabctag", "tag") = "abc"
+ *
+ *
+ * @param str 被切割的字符串
+ * @param beforeAndAfter 截取开始和结束的字符串标识
+ * @return 截取后的字符串
+ * @since 3.1.1
+ */
+ public static String subBetween(CharSequence str, CharSequence beforeAndAfter) {
+ return subBetween(str, beforeAndAfter, beforeAndAfter);
+ }
+
+ /**
+ * 截取指定字符串多段中间部分,不包括标识字符串+ * 栗子: + * + *
+ * StrUtil.subBetweenAll("wx[b]y[z]", "[", "]") = ["b","z"]
+ * StrUtil.subBetweenAll(null, *, *) = []
+ * StrUtil.subBetweenAll(*, null, *) = []
+ * StrUtil.subBetweenAll(*, *, null) = []
+ * StrUtil.subBetweenAll("", "", "") = []
+ * StrUtil.subBetweenAll("", "", "]") = []
+ * StrUtil.subBetweenAll("", "[", "]") = []
+ * StrUtil.subBetweenAll("yabcz", "", "") = []
+ * StrUtil.subBetweenAll("yabcz", "y", "z") = ["abc"]
+ * StrUtil.subBetweenAll("yabczyabcz", "y", "z") = ["abc","abc"]
+ * StrUtil.subBetweenAll("[yabc[zy]abcz]", "[", "]"); = ["zy"] 重叠时只截取内部,
+ *
+ *
+ * @param str 被切割的字符串
+ * @param prefix 截取开始的字符串标识
+ * @param suffix 截取到的字符串标识
+ * @return 截取后的字符串
+ * @author dahuoyzs
+ * @since 5.2.5
+ */
+ public static String[] subBetweenAll(CharSequence str, CharSequence prefix, CharSequence suffix) {
+ if (hasEmpty(str, prefix, suffix) ||
+ // 不包含起始字符串,则肯定没有子串
+ false == contains(str, prefix)) {
+ return new String[0];
+ }
+
+ final List+ * 栗子: + * + *
+ * StrUtil.subBetweenAll(null, *) = []
+ * StrUtil.subBetweenAll(*, null) = []
+ * StrUtil.subBetweenAll(*, *) = []
+ * StrUtil.subBetweenAll("", "") = []
+ * StrUtil.subBetweenAll("", "#") = []
+ * StrUtil.subBetweenAll("gotanks", "") = []
+ * StrUtil.subBetweenAll("#gotanks#", "#") = ["gotanks"]
+ * StrUtil.subBetweenAll("#hello# #world#!", "#") = ["hello", "world"]
+ * StrUtil.subBetweenAll("#hello# world#!", "#"); = ["hello"]
+ *
+ *
+ * @param str 被切割的字符串
+ * @param prefixAndSuffix 截取开始和结束的字符串标识
+ * @return 截取后的字符串
+ * @author gotanks
+ * @since 5.5.0
+ */
+ public static String[] subBetweenAll(CharSequence str, CharSequence prefixAndSuffix) {
+ return subBetweenAll(str, prefixAndSuffix, prefixAndSuffix);
+ }
+
+ // ------------------------------------------------------------------------ repeat
+
+ /**
+ * 重复某个字符
+ *
+ * @param c 被重复的字符
+ * @param count 重复的数目,如果小于等于0则返回""
+ * @return 重复字符字符串
+ */
+ public static String repeat(char c, int count) {
+ if (count <= 0) {
+ return EMPTY;
+ }
+
+ char[] result = new char[count];
+ for (int i = 0; i < count; i++) {
+ result[i] = c;
+ }
+ return new String(result);
+ }
+
+ /**
+ * 重复某个字符串
+ *
+ * @param str 被重复的字符
+ * @param count 重复的数目
+ * @return 重复字符字符串
+ */
+ public static String repeat(CharSequence str, int count) {
+ if (null == str) {
+ return null;
+ }
+ if (count <= 0 || str.length() == 0) {
+ return EMPTY;
+ }
+ if (count == 1) {
+ return str.toString();
+ }
+
+ // 检查
+ final int len = str.length();
+ final long longSize = (long) len * (long) count;
+ final int size = (int) longSize;
+ if (size != longSize) {
+ throw new ArrayIndexOutOfBoundsException("Required String length is too large: " + longSize);
+ }
+
+ final char[] array = new char[size];
+ str.toString().getChars(0, len, array, 0);
+ int n;
+ for (n = len; n < size - n; n <<= 1) {// n <<= 1相当于n *2
+ System.arraycopy(array, 0, array, n, n);
+ }
+ System.arraycopy(array, 0, array, n, size - n);
+ return new String(array);
+ }
+
+ /**
+ * 重复某个字符串到指定长度
+ *
+ * @param str 被重复的字符
+ * @param padLen 指定长度
+ * @return 重复字符字符串
+ * @since 4.3.2
+ */
+ public static String repeatByLength(CharSequence str, int padLen) {
+ if (null == str) {
+ return null;
+ }
+ if (padLen <= 0) {
+ return StrUtil.EMPTY;
+ }
+ final int strLen = str.length();
+ if (strLen == padLen) {
+ return str.toString();
+ } else if (strLen > padLen) {
+ return subPre(str, padLen);
+ }
+
+ // 重复,直到达到指定长度
+ final char[] padding = new char[padLen];
+ for (int i = 0; i < padLen; i++) {
+ padding[i] = str.charAt(i % strLen);
+ }
+ return new String(padding);
+ }
+
+ /**
+ * 重复某个字符串并通过分界符连接
+ *
+ *
+ * StrUtil.repeatAndJoin("?", 5, ",") = "?,?,?,?,?"
+ * StrUtil.repeatAndJoin("?", 0, ",") = ""
+ * StrUtil.repeatAndJoin("?", 5, null) = "?????"
+ *
+ *
+ * @param str 被重复的字符串
+ * @param count 数量
+ * @param conjunction 分界符
+ * @return 连接后的字符串
+ * @since 4.0.1
+ */
+ public static String repeatAndJoin(CharSequence str, int count, CharSequence conjunction) {
+ if (count <= 0) {
+ return EMPTY;
+ }
+ final StrBuilder builder = StrBuilder.create();
+ boolean isFirst = true;
+ while (count-- > 0) {
+ if (isFirst) {
+ isFirst = false;
+ } else if (isNotEmpty(conjunction)) {
+ builder.append(conjunction);
+ }
+ builder.append(str);
+ }
+ return builder.toString();
+ }
+
+ // ------------------------------------------------------------------------ equals
+
+ /**
+ * 比较两个字符串(大小写敏感)。
+ *
+ *
+ * equals(null, null) = true
+ * equals(null, "abc") = false
+ * equals("abc", null) = false
+ * equals("abc", "abc") = true
+ * equals("abc", "ABC") = false
+ *
+ *
+ * @param str1 要比较的字符串1
+ * @param str2 要比较的字符串2
+ * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
+ */
+ public static boolean equals(CharSequence str1, CharSequence str2) {
+ return equals(str1, str2, false);
+ }
+
+ /**
+ * 比较两个字符串(大小写不敏感)。
+ *
+ *
+ * equalsIgnoreCase(null, null) = true
+ * equalsIgnoreCase(null, "abc") = false
+ * equalsIgnoreCase("abc", null) = false
+ * equalsIgnoreCase("abc", "abc") = true
+ * equalsIgnoreCase("abc", "ABC") = true
+ *
+ *
+ * @param str1 要比较的字符串1
+ * @param str2 要比较的字符串2
+ * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
+ */
+ public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
+ return equals(str1, str2, true);
+ }
+
+ /**
+ * 比较两个字符串是否相等。
+ *
+ * @param str1 要比较的字符串1
+ * @param str2 要比较的字符串2
+ * @param ignoreCase 是否忽略大小写
+ * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
+ * @since 3.2.0
+ */
+ public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
+ if (null == str1) {
+ // 只有两个都为null才判断相等
+ return str2 == null;
+ }
+ if (null == str2) {
+ // 字符串2空,字符串1非空,直接false
+ return false;
+ }
+
+ if (ignoreCase) {
+ return str1.toString().equalsIgnoreCase(str2.toString());
+ } else {
+ return str1.toString().contentEquals(str2);
+ }
+ }
+
+ /**
+ * 给定字符串是否与提供的中任一字符串相同(忽略大小写),相同则返回{@code true},没有相同的返回{@code false}
+ * StrUtil.padPre(null, *, *);//null
+ * StrUtil.padPre("1", 3, "ABC");//"AB1"
+ * StrUtil.padPre("123", 2, "ABC");//"12"
+ *
+ *
+ * @param str 字符串
+ * @param minLength 最小长度
+ * @param padStr 补充的字符
+ * @return 补充后的字符串
+ */
+ public static String padPre(CharSequence str, int minLength, CharSequence padStr) {
+ if (null == str) {
+ return null;
+ }
+ final int strLen = str.length();
+ if (strLen == minLength) {
+ return str.toString();
+ } else if (strLen > minLength) {
+ return subPre(str, minLength);
+ }
+
+ return repeatByLength(padStr, minLength - strLen).concat(str.toString());
+ }
+
+ /**
+ * 补充字符串以满足最小长度
+ *
+ *
+ * StrUtil.padPre(null, *, *);//null
+ * StrUtil.padPre("1", 3, '0');//"001"
+ * StrUtil.padPre("123", 2, '0');//"12"
+ *
+ *
+ * @param str 字符串
+ * @param minLength 最小长度
+ * @param padChar 补充的字符
+ * @return 补充后的字符串
+ */
+ public static String padPre(CharSequence str, int minLength, char padChar) {
+ if (null == str) {
+ return null;
+ }
+ final int strLen = str.length();
+ if (strLen == minLength) {
+ return str.toString();
+ } else if (strLen > minLength) {
+ return subPre(str, minLength);
+ }
+
+ return repeat(padChar, minLength - strLen).concat(str.toString());
+ }
+
+ /**
+ * 补充字符串以满足最小长度
+ *
+ *
+ * StrUtil.padAfter(null, *, *);//null
+ * StrUtil.padAfter("1", 3, '0');//"100"
+ * StrUtil.padAfter("123", 2, '0');//"23"
+ *
+ *
+ * @param str 字符串,如果为{@code null},直接返回null
+ * @param minLength 最小长度
+ * @param padChar 补充的字符
+ * @return 补充后的字符串
+ */
+ public static String padAfter(CharSequence str, int minLength, char padChar) {
+ if (null == str) {
+ return null;
+ }
+ final int strLen = str.length();
+ if (strLen == minLength) {
+ return str.toString();
+ } else if (strLen > minLength) {
+ return sub(str, strLen - minLength, strLen);
+ }
+
+ return str.toString().concat(repeat(padChar, minLength - strLen));
+ }
+
+ /**
+ * 补充字符串以满足最小长度
+ *
+ *
+ * StrUtil.padAfter(null, *, *);//null
+ * StrUtil.padAfter("1", 3, "ABC");//"1AB"
+ * StrUtil.padAfter("123", 2, "ABC");//"23"
+ *
+ *
+ * @param str 字符串,如果为{@code null},直接返回null
+ * @param minLength 最小长度
+ * @param padStr 补充的字符
+ * @return 补充后的字符串
+ * @since 4.3.2
+ */
+ public static String padAfter(CharSequence str, int minLength, CharSequence padStr) {
+ if (null == str) {
+ return null;
+ }
+ final int strLen = str.length();
+ if (strLen == minLength) {
+ return str.toString();
+ } else if (strLen > minLength) {
+ return subSufByLength(str, minLength);
+ }
+
+ return str.toString().concat(repeatByLength(padStr, minLength - strLen));
+ }
+
+ // ------------------------------------------------------------------------ center
+
+ /**
+ * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
+ *
+ *
+ * StrUtil.center(null, *) = null
+ * StrUtil.center("", 4) = " "
+ * StrUtil.center("ab", -1) = "ab"
+ * StrUtil.center("ab", 4) = " ab "
+ * StrUtil.center("abcd", 2) = "abcd"
+ * StrUtil.center("a", 4) = " a "
+ *
+ *
+ * @param str 字符串
+ * @param size 指定长度
+ * @return 补充后的字符串
+ * @since 4.3.2
+ */
+ public static String center(CharSequence str, final int size) {
+ return center(str, size, CharUtil.SPACE);
+ }
+
+ /**
+ * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
+ *
+ *
+ * StrUtil.center(null, *, *) = null
+ * StrUtil.center("", 4, ' ') = " "
+ * StrUtil.center("ab", -1, ' ') = "ab"
+ * StrUtil.center("ab", 4, ' ') = " ab "
+ * StrUtil.center("abcd", 2, ' ') = "abcd"
+ * StrUtil.center("a", 4, ' ') = " a "
+ * StrUtil.center("a", 4, 'y') = "yayy"
+ * StrUtil.center("abc", 7, ' ') = " abc "
+ *
+ *
+ * @param str 字符串
+ * @param size 指定长度
+ * @param padChar 两边补充的字符
+ * @return 补充后的字符串
+ * @since 4.3.2
+ */
+ public static String center(CharSequence str, final int size, char padChar) {
+ if (str == null || size <= 0) {
+ return str(str);
+ }
+ final int strLen = str.length();
+ final int pads = size - strLen;
+ if (pads <= 0) {
+ return str.toString();
+ }
+ str = padPre(str, strLen + pads / 2, padChar);
+ str = padAfter(str, size, padChar);
+ return str.toString();
+ }
+
+ /**
+ * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
+ *
+ *
+ * StrUtil.center(null, *, *) = null
+ * StrUtil.center("", 4, " ") = " "
+ * StrUtil.center("ab", -1, " ") = "ab"
+ * StrUtil.center("ab", 4, " ") = " ab "
+ * StrUtil.center("abcd", 2, " ") = "abcd"
+ * StrUtil.center("a", 4, " ") = " a "
+ * StrUtil.center("a", 4, "yz") = "yayz"
+ * StrUtil.center("abc", 7, null) = " abc "
+ * StrUtil.center("abc", 7, "") = " abc "
+ *
+ *
+ * @param str 字符串
+ * @param size 指定长度
+ * @param padStr 两边补充的字符串
+ * @return 补充后的字符串
+ */
+ public static String center(CharSequence str, final int size, CharSequence padStr) {
+ if (str == null || size <= 0) {
+ return str(str);
+ }
+ if (isEmpty(padStr)) {
+ padStr = SPACE;
+ }
+ final int strLen = str.length();
+ final int pads = size - strLen;
+ if (pads <= 0) {
+ return str.toString();
+ }
+ str = padPre(str, strLen + pads / 2, padStr);
+ str = padAfter(str, size, padStr);
+ return str.toString();
+ }
+
+ // ------------------------------------------------------------------------ str
+
+ /**
+ * {@link CharSequence} 转为字符串,null安全
+ *
+ * @param cs {@link CharSequence}
+ * @return 字符串
+ */
+ public static String str(CharSequence cs) {
+ return null == cs ? null : cs.toString();
+ }
+
+ // ------------------------------------------------------------------------ count
+
+ /**
+ * 统计指定内容中包含指定字符串的数量
+ * StrUtil.count(null, *) = 0
+ * StrUtil.count("", *) = 0
+ * StrUtil.count("abba", null) = 0
+ * StrUtil.count("abba", "") = 0
+ * StrUtil.count("abba", "a") = 2
+ * StrUtil.count("abba", "ab") = 1
+ * StrUtil.count("abba", "xxx") = 0
+ *
+ *
+ * @param content 被查找的字符串
+ * @param strForSearch 需要查找的字符串
+ * @return 查找到的个数
+ */
+ public static int count(CharSequence content, CharSequence strForSearch) {
+ if (hasEmpty(content, strForSearch) || strForSearch.length() > content.length()) {
+ return 0;
+ }
+
+ int count = 0;
+ int idx = 0;
+ final String content2 = content.toString();
+ final String strForSearch2 = strForSearch.toString();
+ while ((idx = content2.indexOf(strForSearch2, idx)) > -1) {
+ count++;
+ idx += strForSearch.length();
+ }
+ return count;
+ }
+
+ /**
+ * 统计指定内容中包含指定字符的数量
+ *
+ * @param content 内容
+ * @param charForSearch 被统计的字符
+ * @return 包含数量
+ */
+ public static int count(CharSequence content, char charForSearch) {
+ int count = 0;
+ if (isEmpty(content)) {
+ return 0;
+ }
+ int contentLength = content.length();
+ for (int i = 0; i < contentLength; i++) {
+ if (charForSearch == content.charAt(i)) {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ // ------------------------------------------------------------------------ compare
+
+ /**
+ * 比较两个字符串,用于排序
+ *
+ *
+ * StrUtil.compare(null, null, *) = 0
+ * StrUtil.compare(null , "a", true) < 0
+ * StrUtil.compare(null , "a", false) > 0
+ * StrUtil.compare("a", null, true) > 0
+ * StrUtil.compare("a", null, false) < 0
+ * StrUtil.compare("abc", "abc", *) = 0
+ * StrUtil.compare("a", "b", *) < 0
+ * StrUtil.compare("b", "a", *) > 0
+ * StrUtil.compare("a", "B", *) > 0
+ * StrUtil.compare("ab", "abc", *) < 0
+ *
+ *
+ * @param str1 字符串1
+ * @param str2 字符串2
+ * @param nullIsLess {@code null} 值是否排在前(null是否小于非空值)
+ * @return 排序值。负数:str1 < str2,正数:str1 > str2, 0:str1 == str2
+ */
+ public static int compare(final CharSequence str1, final CharSequence str2, final boolean nullIsLess) {
+ if (str1 == str2) {
+ return 0;
+ }
+ if (str1 == null) {
+ return nullIsLess ? -1 : 1;
+ }
+ if (str2 == null) {
+ return nullIsLess ? 1 : -1;
+ }
+ return str1.toString().compareTo(str2.toString());
+ }
+
+ /**
+ * 比较两个字符串,用于排序,大小写不敏感
+ *
+ *
+ * StrUtil.compareIgnoreCase(null, null, *) = 0
+ * StrUtil.compareIgnoreCase(null , "a", true) < 0
+ * StrUtil.compareIgnoreCase(null , "a", false) > 0
+ * StrUtil.compareIgnoreCase("a", null, true) > 0
+ * StrUtil.compareIgnoreCase("a", null, false) < 0
+ * StrUtil.compareIgnoreCase("abc", "abc", *) = 0
+ * StrUtil.compareIgnoreCase("abc", "ABC", *) = 0
+ * StrUtil.compareIgnoreCase("a", "b", *) < 0
+ * StrUtil.compareIgnoreCase("b", "a", *) > 0
+ * StrUtil.compareIgnoreCase("a", "B", *) < 0
+ * StrUtil.compareIgnoreCase("A", "b", *) < 0
+ * StrUtil.compareIgnoreCase("ab", "abc", *) < 0
+ *
+ *
+ * @param str1 字符串1
+ * @param str2 字符串2
+ * @param nullIsLess {@code null} 值是否排在前(null是否小于非空值)
+ * @return 排序值。负数:str1 < str2,正数:str1 > str2, 0:str1 == str2
+ */
+ public static int compareIgnoreCase(CharSequence str1, CharSequence str2, boolean nullIsLess) {
+ if (str1 == str2) {
+ return 0;
+ }
+ if (str1 == null) {
+ return nullIsLess ? -1 : 1;
+ }
+ if (str2 == null) {
+ return nullIsLess ? 1 : -1;
+ }
+ return str1.toString().compareToIgnoreCase(str2.toString());
+ }
+
+ /**
+ * 比较两个版本
+ * StrUtil.compareVersion(null, "v1") < 0
+ * StrUtil.compareVersion("v1", "v1") = 0
+ * StrUtil.compareVersion(null, null) = 0
+ * StrUtil.compareVersion("v1", null) > 0
+ * StrUtil.compareVersion("1.0.0", "1.0.2") < 0
+ * StrUtil.compareVersion("1.0.2", "1.0.2a") < 0
+ * StrUtil.compareVersion("1.13.0", "1.12.1c") > 0
+ * StrUtil.compareVersion("V0.0.20170102", "V0.0.20170101") > 0
+ *
+ *
+ * @param version1 版本1
+ * @param version2 版本2
+ * @return 排序值。负数:version1 < version2,正数:version1 > version2, 0:version1 == version2
+ * @since 4.0.2
+ */
+ public static int compareVersion(CharSequence version1, CharSequence version2) {
+ return VersionComparator.INSTANCE.compare(str(version1), str(version2));
+ }
+
+ // ------------------------------------------------------------------------ append and prepend
+
+ /**
+ * 如果给定字符串不是以给定的一个或多个字符串为结尾,则在尾部添加结尾字符串+ * 1. 大写字母包括A-Z + * 2. 其它非字母的Unicode符都算作大写 + *+ * + * @param str 被检查的字符串 + * @return 是否全部为大写 + * @since 4.2.2 + */ + public static boolean isUpperCase(CharSequence str) { + if (null == str) { + return false; + } + final int len = str.length(); + for (int i = 0; i < len; i++) { + if (Character.isLowerCase(str.charAt(i))) { + return false; + } + } + return true; + } + + /** + * 给定字符串中的字母是否全部为小写,判断依据如下: + * + *
+ * 1. 小写字母包括a-z + * 2. 其它非字母的Unicode符都算作小写 + *+ * + * @param str 被检查的字符串 + * @return 是否全部为小写 + * @since 4.2.2 + */ + public static boolean isLowerCase(CharSequence str) { + if (null == str) { + return false; + } + final int len = str.length(); + for (int i = 0; i < len; i++) { + if (Character.isUpperCase(str.charAt(i))) { + return false; + } + } + return true; + } + + /** + * 切换给定字符串中的大小写。大写转小写,小写转大写。 + * + *
+ * StrUtil.swapCase(null) = null
+ * StrUtil.swapCase("") = ""
+ * StrUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
+ *
+ *
+ * @param str 字符串
+ * @return 交换后的字符串
+ * @since 4.3.2
+ */
+ public static String swapCase(final String str) {
+ if (isEmpty(str)) {
+ return str;
+ }
+
+ final char[] buffer = str.toCharArray();
+
+ for (int i = 0; i < buffer.length; i++) {
+ final char ch = buffer[i];
+ if (Character.isUpperCase(ch)) {
+ buffer[i] = Character.toLowerCase(ch);
+ } else if (Character.isTitleCase(ch)) {
+ buffer[i] = Character.toLowerCase(ch);
+ } else if (Character.isLowerCase(ch)) {
+ buffer[i] = Character.toUpperCase(ch);
+ }
+ }
+ return new String(buffer);
+ }
+
+ /**
+ * 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。+ * HelloWorld=》hello_world + * Hello_World=》hello_world + * HelloWorld_test=》hello_world_test + *+ * + * @param str 转换前的驼峰式命名的字符串,也可以为下划线形式 + * @return 转换后下划线方式命名的字符串 + */ + public static String toUnderlineCase(CharSequence str) { + return toSymbolCase(str, CharUtil.UNDERLINE); + } + + /** + * 将驼峰式命名的字符串转换为使用符号连接方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
+ * getName =》name + * setName =》name + * isName =》name + *+ * + * @param getOrSetMethodName Get或Set方法名 + * @return 如果是set或get方法名,返回field, 否则null + */ + public static String getGeneralField(CharSequence getOrSetMethodName) { + final String getOrSetMethodNameStr = getOrSetMethodName.toString(); + if (getOrSetMethodNameStr.startsWith("get") || getOrSetMethodNameStr.startsWith("set")) { + return removePreAndLowerFirst(getOrSetMethodName, 3); + } else if (getOrSetMethodNameStr.startsWith("is")) { + return removePreAndLowerFirst(getOrSetMethodName, 2); + } + return null; + } + + /** + * 生成set方法名
字符串是否为空白,空白的定义如下:
- *例:
- *注意:该方法与 {@link #isEmpty(CharSequence)} 的区别是: - * 该方法会校验空白字符,且性能相对于 {@link #isEmpty(CharSequence)} 略慢。
- *建议:
- *如果对象是字符串是否为空白,空白的定义如下:
*字符串是否为非空白,非空白的定义如下:
- *例:
- *注意:该方法与 {@link #isNotEmpty(CharSequence)} 的区别是: - * 该方法会校验空白字符,且性能相对于 {@link #isNotEmpty(CharSequence)} 略慢。
- *建议:仅对于客户端(或第三方接口)传入的参数使用该方法。
- * - * @param str 被检测的字符串 - * @return 是否为非空 - * @see StrUtil#isBlank(CharSequence) - */ - public static boolean isNotBlank(CharSequence str) { - return false == isBlank(str); - } - - /** - *指定字符串数组中,是否包含空字符串。
- *如果指定的字符串数组的长度为 0,或者其中的任意一个元素是空字符串,则返回 true。
- *例:
- *注意:该方法与 {@link #isAllBlank(CharSequence...)} 的区别在于:
- *指定字符串数组中的元素,是否全部为空字符串。
- *如果指定的字符串数组的长度为 0,或者所有元素都是空字符串,则返回 true。
- *例:
- *注意:该方法与 {@link #hasBlank(CharSequence...)} 的区别在于:
- *字符串是否为空,空的定义如下:
- *例:
- *注意:该方法与 {@link #isBlank(CharSequence)} 的区别是:该方法不校验空白字符。
- *建议:
- *如果对象是字符串是否为空串,空的定义如下:
字符串是否为非空白,非空白的定义如下:
- *例:
- *注意:该方法与 {@link #isNotBlank(CharSequence)} 的区别是:该方法不校验空白字符。
- *建议:该方法建议用于工具类或任何可以预期的方法参数的校验中。
- * - * @param str 被检测的字符串 - * @return 是否为非空 - * @see StrUtil#isEmpty(CharSequence) - */ - public static boolean isNotEmpty(CharSequence str) { - return false == isEmpty(str); - } - - /** - * 当给定字符串为null时,转换为Empty - * - * @param str 被检查的字符串 - * @return 原字符串或者空串 - * @see #nullToEmpty(CharSequence) - * @since 4.6.3 - */ - public static String emptyIfNull(CharSequence str) { - return nullToEmpty(str); - } - - /** - * 当给定字符串为null时,转换为Empty - * - * @param str 被转换的字符串 - * @return 转换后的字符串 - */ - public static String nullToEmpty(CharSequence str) { - return nullToDefault(str, EMPTY); - } - - /** - * 如果字符串是 {@code null},则返回指定默认字符串,否则返回字符串本身。 - * - *
- * nullToDefault(null, "default") = "default"
- * nullToDefault("", "default") = ""
- * nullToDefault(" ", "default") = " "
- * nullToDefault("bat", "default") = "bat"
- *
- *
- * @param str 要转换的字符串
- * @param defaultStr 默认字符串
- * @return 字符串本身或指定的默认字符串
- */
- public static String nullToDefault(CharSequence str, String defaultStr) {
- return (str == null) ? defaultStr : str.toString();
- }
-
- /**
- * 如果字符串是{@code null}或者"",则返回指定默认字符串,否则返回字符串本身。
- *
- *
- * emptyToDefault(null, "default") = "default"
- * emptyToDefault("", "default") = "default"
- * emptyToDefault(" ", "default") = " "
- * emptyToDefault("bat", "default") = "bat"
- *
- *
- * @param str 要转换的字符串
- * @param defaultStr 默认字符串
- * @return 字符串本身或指定的默认字符串
- * @since 4.1.0
- */
- public static String emptyToDefault(CharSequence str, String defaultStr) {
- return isEmpty(str) ? defaultStr : str.toString();
- }
-
- /**
- * 如果字符串是{@code null}或者""或者空白,则返回指定默认字符串,否则返回字符串本身。
- *
- *
- * emptyToDefault(null, "default") = "default"
- * emptyToDefault("", "default") = "default"
- * emptyToDefault(" ", "default") = "default"
- * emptyToDefault("bat", "default") = "bat"
- *
- *
- * @param str 要转换的字符串
- * @param defaultStr 默认字符串
- * @return 字符串本身或指定的默认字符串
- * @since 4.1.0
- */
- public static String blankToDefault(CharSequence str, String defaultStr) {
- return isBlank(str) ? defaultStr : str.toString();
- }
-
- /**
- * 当给定字符串为空字符串时,转换为{@code null}
- *
- * @param str 被转换的字符串
- * @return 转换后的字符串
- */
- public static String emptyToNull(CharSequence str) {
- return isEmpty(str) ? null : str.toString();
- }
-
- /**
- * 是否包含空字符串。
- *如果指定的字符串数组的长度为 0,或者其中的任意一个元素是空字符串,则返回 true。
- *例:
- *注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:
- *指定字符串数组中的元素,是否全部为空字符串。
- *如果指定的字符串数组的长度为 0,或者所有元素都是空字符串,则返回 true。
- *例:
- *注意:该方法与 {@link #hasEmpty(CharSequence...)} 的区别在于:
- *指定字符串数组中的元素,是否都不为空字符串。
- *如果指定的字符串数组的长度不为 0,或者所有元素都不是空字符串,则返回 true。
- *例:
- *注意:该方法与 {@link #isAllEmpty(CharSequence...)} 的区别在于:
- *- * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 - * - *
- * trim(null) = null
- * trim("") = ""
- * trim(" ") = ""
- * trim("abc") = "abc"
- * trim(" abc ") = "abc"
- *
- *
- * @param str 要处理的字符串
- * @return 除去头尾空白的字符串,如果原字串为{@code null},则返回{@code null}
- */
- public static String trim(CharSequence str) {
- return (null == str) ? null : trim(str, 0);
- }
-
/**
* 给定字符串数组全部做去首尾空格
*
@@ -807,2044 +298,11 @@ public class StrUtil {
for (int i = 0; i < strs.length; i++) {
str = strs[i];
if (null != str) {
- strs[i] = str.trim();
+ strs[i] = trim(str);
}
}
}
- /**
- * 除去字符串头尾部的空白,如果字符串是{@code null},返回{@code ""}。
- *
- *
- * StrUtil.trimToEmpty(null) = ""
- * StrUtil.trimToEmpty("") = ""
- * StrUtil.trimToEmpty(" ") = ""
- * StrUtil.trimToEmpty("abc") = "abc"
- * StrUtil.trimToEmpty(" abc ") = "abc"
- *
- *
- * @param str 字符串
- * @return 去除两边空白符后的字符串, 如果为null返回""
- * @since 3.1.1
- */
- public static String trimToEmpty(CharSequence str) {
- return str == null ? EMPTY : trim(str);
- }
-
- /**
- * 除去字符串头尾部的空白,如果字符串是{@code null}或者"",返回{@code null}。
- *
- *
- * StrUtil.trimToNull(null) = null
- * StrUtil.trimToNull("") = null
- * StrUtil.trimToNull(" ") = null
- * StrUtil.trimToNull("abc") = "abc"
- * StrUtil.trimToEmpty(" abc ") = "abc"
- *
- *
- * @param str 字符串
- * @return 去除两边空白符后的字符串, 如果为空返回null
- * @since 3.2.1
- */
- public static String trimToNull(CharSequence str) {
- final String trimStr = trim(str);
- return EMPTY.equals(trimStr) ? null : trimStr;
- }
-
- /**
- * 除去字符串头部的空白,如果字符串是{@code null},则返回{@code null}。
- *
- * - * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 - * - *
- * trimStart(null) = null
- * trimStart("") = ""
- * trimStart("abc") = "abc"
- * trimStart(" abc") = "abc"
- * trimStart("abc ") = "abc "
- * trimStart(" abc ") = "abc "
- *
- *
- * @param str 要处理的字符串
- * @return 除去空白的字符串,如果原字串为{@code null}或结果字符串为{@code ""},则返回 {@code null}
- */
- public static String trimStart(CharSequence str) {
- return trim(str, -1);
- }
-
- /**
- * 除去字符串尾部的空白,如果字符串是{@code null},则返回{@code null}。
- *
- * - * 注意,和{@link String#trim()}不同,此方法使用{@link CharUtil#isBlankChar(char)} 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。 - * - *
- * trimEnd(null) = null
- * trimEnd("") = ""
- * trimEnd("abc") = "abc"
- * trimEnd(" abc") = " abc"
- * trimEnd("abc ") = "abc"
- * trimEnd(" abc ") = " abc"
- *
- *
- * @param str 要处理的字符串
- * @return 除去空白的字符串,如果原字串为{@code null}或结果字符串为{@code ""},则返回 {@code null}
- */
- public static String trimEnd(CharSequence str) {
- return trim(str, 1);
- }
-
- /**
- * 除去字符串头尾部的空白符,如果字符串是{@code null},依然返回{@code null}。
- *
- * @param str 要处理的字符串
- * @param mode {@code -1}表示trimStart,{@code 0}表示trim全部, {@code 1}表示trimEnd
- * @return 除去指定字符后的的字符串,如果原字串为{@code null},则返回{@code null}
- */
- public static String trim(CharSequence str, int mode) {
- String result;
- if (str == null) {
- result = null;
- } else {
- int length = str.length();
- int start = 0;
- int end = length;// 扫描字符串头部
- if (mode <= 0) {
- while ((start < end) && (CharUtil.isBlankChar(str.charAt(start)))) {
- start++;
- }
- }// 扫描字符串尾部
- if (mode >= 0) {
- while ((start < end) && (CharUtil.isBlankChar(str.charAt(end - 1)))) {
- end--;
- }
- }
- if ((start > 0) || (end < length)) {
- result = str.toString().substring(start, end);
- } else {
- result = str.toString();
- }
- }
-
- return result;
- }
-
- /**
- * 字符串是否以给定字符开始
- *
- * @param str 字符串
- * @param c 字符
- * @return 是否开始
- */
- public static boolean startWith(CharSequence str, char c) {
- if (isEmpty(str)) {
- return false;
- }
- return c == str.charAt(0);
- }
-
- /**
- * 是否以指定字符串开头- * getName =》name - * setName =》name - * isName =》name - *- * - * @param getOrSetMethodName Get或Set方法名 - * @return 如果是set或get方法名,返回field, 否则null - */ - public static String getGeneralField(CharSequence getOrSetMethodName) { - final String getOrSetMethodNameStr = getOrSetMethodName.toString(); - if (getOrSetMethodNameStr.startsWith("get") || getOrSetMethodNameStr.startsWith("set")) { - return removePreAndLowerFirst(getOrSetMethodName, 3); - } else if (getOrSetMethodNameStr.startsWith("is")) { - return removePreAndLowerFirst(getOrSetMethodName, 2); - } - return null; - } - - /** - * 生成set方法名
- * 1. \r - * 1. \n - *- * - * @param str 字符串 - * @return 处理后的字符串 - * @since 4.2.2 - */ - public static String removeAllLineBreaks(CharSequence str) { - return removeAll(str, C_CR, C_LF); - } - - /** - * 去掉首部指定长度的字符串并将剩余字符串首字母小写
- * StrUtil.subSufByLength("abcde", 3) = "cde"
- * StrUtil.subSufByLength("abcde", 0) = ""
- * StrUtil.subSufByLength("abcde", -5) = ""
- * StrUtil.subSufByLength("abcde", -1) = ""
- * StrUtil.subSufByLength("abcde", 5) = "abcde"
- * StrUtil.subSufByLength("abcde", 10) = "abcde"
- * StrUtil.subSufByLength(null, 3) = null
- *
- *
- * @param string 字符串
- * @param length 切割长度
- * @return 切割后后剩余的后半部分字符串
- * @since 4.0.1
- */
- public static String subSufByLength(CharSequence string, int length) {
- if (isEmpty(string)) {
- return null;
- }
- if (length <= 0) {
- return EMPTY;
- }
- return sub(string, -length, string.length());
- }
-
- /**
- * 截取字符串,从指定位置开始,截取指定长度的字符串
- * StrUtil.subBefore(null, *, false) = null
- * StrUtil.subBefore("", *, false) = ""
- * StrUtil.subBefore("abc", "a", false) = ""
- * StrUtil.subBefore("abcba", "b", false) = "a"
- * StrUtil.subBefore("abc", "c", false) = "ab"
- * StrUtil.subBefore("abc", "d", false) = "abc"
- * StrUtil.subBefore("abc", "", false) = ""
- * StrUtil.subBefore("abc", null, false) = "abc"
- *
- *
- * @param string 被查找的字符串
- * @param separator 分隔字符串(不包括)
- * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
- * @return 切割后的字符串
- * @since 3.1.1
- */
- public static String subBefore(CharSequence string, CharSequence separator, boolean isLastSeparator) {
- if (isEmpty(string) || separator == null) {
- return null == string ? null : string.toString();
- }
-
- final String str = string.toString();
- final String sep = separator.toString();
- if (sep.isEmpty()) {
- return EMPTY;
- }
- final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
- if (INDEX_NOT_FOUND == pos) {
- return str;
- }
- if (0 == pos) {
- return EMPTY;
- }
- return str.substring(0, pos);
- }
-
- /**
- * 截取分隔字符串之前的字符串,不包括分隔字符串
- * StrUtil.subBefore(null, *, false) = null
- * StrUtil.subBefore("", *, false) = ""
- * StrUtil.subBefore("abc", 'a', false) = ""
- * StrUtil.subBefore("abcba", 'b', false) = "a"
- * StrUtil.subBefore("abc", 'c', false) = "ab"
- * StrUtil.subBefore("abc", 'd', false) = "abc"
- *
- *
- * @param string 被查找的字符串
- * @param separator 分隔字符串(不包括)
- * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
- * @return 切割后的字符串
- * @since 4.1.15
- */
- public static String subBefore(CharSequence string, char separator, boolean isLastSeparator) {
- if (isEmpty(string)) {
- return null == string ? null : EMPTY;
- }
-
- final String str = string.toString();
- final int pos = isLastSeparator ? str.lastIndexOf(separator) : str.indexOf(separator);
- if (INDEX_NOT_FOUND == pos) {
- return str;
- }
- if (0 == pos) {
- return EMPTY;
- }
- return str.substring(0, pos);
- }
-
- /**
- * 截取分隔字符串之后的字符串,不包括分隔字符串
- * StrUtil.subAfter(null, *, false) = null
- * StrUtil.subAfter("", *, false) = ""
- * StrUtil.subAfter(*, null, false) = ""
- * StrUtil.subAfter("abc", "a", false) = "bc"
- * StrUtil.subAfter("abcba", "b", false) = "cba"
- * StrUtil.subAfter("abc", "c", false) = ""
- * StrUtil.subAfter("abc", "d", false) = ""
- * StrUtil.subAfter("abc", "", false) = "abc"
- *
- *
- * @param string 被查找的字符串
- * @param separator 分隔字符串(不包括)
- * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
- * @return 切割后的字符串
- * @since 3.1.1
- */
- public static String subAfter(CharSequence string, CharSequence separator, boolean isLastSeparator) {
- if (isEmpty(string)) {
- return null == string ? null : EMPTY;
- }
- if (separator == null) {
- return EMPTY;
- }
- final String str = string.toString();
- final String sep = separator.toString();
- final int pos = isLastSeparator ? str.lastIndexOf(sep) : str.indexOf(sep);
- if (INDEX_NOT_FOUND == pos || (string.length() - 1) == pos) {
- return EMPTY;
- }
- return str.substring(pos + separator.length());
- }
-
- /**
- * 截取分隔字符串之后的字符串,不包括分隔字符串
- * StrUtil.subAfter(null, *, false) = null
- * StrUtil.subAfter("", *, false) = ""
- * StrUtil.subAfter("abc", 'a', false) = "bc"
- * StrUtil.subAfter("abcba", 'b', false) = "cba"
- * StrUtil.subAfter("abc", 'c', false) = ""
- * StrUtil.subAfter("abc", 'd', false) = ""
- *
- *
- * @param string 被查找的字符串
- * @param separator 分隔字符串(不包括)
- * @param isLastSeparator 是否查找最后一个分隔字符串(多次出现分隔字符串时选取最后一个),true为选取最后一个
- * @return 切割后的字符串
- * @since 4.1.15
- */
- public static String subAfter(CharSequence string, char separator, boolean isLastSeparator) {
- if (isEmpty(string)) {
- return null == string ? null : EMPTY;
- }
- final String str = string.toString();
- final int pos = isLastSeparator ? str.lastIndexOf(separator) : str.indexOf(separator);
- if (INDEX_NOT_FOUND == pos) {
- return EMPTY;
- }
- return str.substring(pos + 1);
- }
-
- /**
- * 截取指定字符串中间部分,不包括标识字符串- * 栗子: - * - *
- * StrUtil.subBetween("wx[b]yz", "[", "]") = "b"
- * StrUtil.subBetween(null, *, *) = null
- * StrUtil.subBetween(*, null, *) = null
- * StrUtil.subBetween(*, *, null) = null
- * StrUtil.subBetween("", "", "") = ""
- * StrUtil.subBetween("", "", "]") = null
- * StrUtil.subBetween("", "[", "]") = null
- * StrUtil.subBetween("yabcz", "", "") = ""
- * StrUtil.subBetween("yabcz", "y", "z") = "abc"
- * StrUtil.subBetween("yabczyabcz", "y", "z") = "abc"
- *
- *
- * @param str 被切割的字符串
- * @param before 截取开始的字符串标识
- * @param after 截取到的字符串标识
- * @return 截取后的字符串
- * @since 3.1.1
- */
- public static String subBetween(CharSequence str, CharSequence before, CharSequence after) {
- if (str == null || before == null || after == null) {
- return null;
- }
-
- final String str2 = str.toString();
- final String before2 = before.toString();
- final String after2 = after.toString();
-
- final int start = str2.indexOf(before2);
- if (start != INDEX_NOT_FOUND) {
- final int end = str2.indexOf(after2, start + before2.length());
- if (end != INDEX_NOT_FOUND) {
- return str2.substring(start + before2.length(), end);
- }
- }
- return null;
- }
-
- /**
- * 截取指定字符串中间部分,不包括标识字符串- * 栗子: - * - *
- * StrUtil.subBetween(null, *) = null
- * StrUtil.subBetween("", "") = ""
- * StrUtil.subBetween("", "tag") = null
- * StrUtil.subBetween("tagabctag", null) = null
- * StrUtil.subBetween("tagabctag", "") = ""
- * StrUtil.subBetween("tagabctag", "tag") = "abc"
- *
- *
- * @param str 被切割的字符串
- * @param beforeAndAfter 截取开始和结束的字符串标识
- * @return 截取后的字符串
- * @since 3.1.1
- */
- public static String subBetween(CharSequence str, CharSequence beforeAndAfter) {
- return subBetween(str, beforeAndAfter, beforeAndAfter);
- }
-
- /**
- * 截取指定字符串多段中间部分,不包括标识字符串- * 栗子: - * - *
- * StrUtil.subBetweenAll("wx[b]y[z]", "[", "]") = ["b","z"]
- * StrUtil.subBetweenAll(null, *, *) = []
- * StrUtil.subBetweenAll(*, null, *) = []
- * StrUtil.subBetweenAll(*, *, null) = []
- * StrUtil.subBetweenAll("", "", "") = []
- * StrUtil.subBetweenAll("", "", "]") = []
- * StrUtil.subBetweenAll("", "[", "]") = []
- * StrUtil.subBetweenAll("yabcz", "", "") = []
- * StrUtil.subBetweenAll("yabcz", "y", "z") = ["abc"]
- * StrUtil.subBetweenAll("yabczyabcz", "y", "z") = ["abc","abc"]
- * StrUtil.subBetweenAll("[yabc[zy]abcz]", "[", "]"); = ["zy"] 重叠时只截取内部,
- *
- *
- * @param str 被切割的字符串
- * @param prefix 截取开始的字符串标识
- * @param suffix 截取到的字符串标识
- * @return 截取后的字符串
- * @author dahuoyzs
- * @since 5.2.5
- */
- public static String[] subBetweenAll(CharSequence str, CharSequence prefix, CharSequence suffix) {
- if (hasEmpty(str, prefix, suffix) ||
- // 不包含起始字符串,则肯定没有子串
- false == contains(str, prefix)) {
- return new String[0];
- }
-
- final List- * 栗子: - * - *
- * StrUtil.subBetweenAll(null, *) = []
- * StrUtil.subBetweenAll(*, null) = []
- * StrUtil.subBetweenAll(*, *) = []
- * StrUtil.subBetweenAll("", "") = []
- * StrUtil.subBetweenAll("", "#") = []
- * StrUtil.subBetweenAll("gotanks", "") = []
- * StrUtil.subBetweenAll("#gotanks#", "#") = ["gotanks"]
- * StrUtil.subBetweenAll("#hello# #world#!", "#") = ["hello", "world"]
- * StrUtil.subBetweenAll("#hello# world#!", "#"); = ["hello"]
- *
- *
- * @param str 被切割的字符串
- * @param prefixAndSuffix 截取开始和结束的字符串标识
- * @return 截取后的字符串
- * @author gotanks
- * @since 5.5.0
- */
- public static String[] subBetweenAll(CharSequence str, CharSequence prefixAndSuffix) {
- return subBetweenAll(str, prefixAndSuffix, prefixAndSuffix);
- }
-
- /**
- * 给定字符串是否被字符包围
- *
- * @param str 字符串
- * @param prefix 前缀
- * @param suffix 后缀
- * @return 是否包围,空串不包围
- */
- public static boolean isSurround(CharSequence str, CharSequence prefix, CharSequence suffix) {
- if (StrUtil.isBlank(str)) {
- return false;
- }
- if (str.length() < (prefix.length() + suffix.length())) {
- return false;
- }
-
- final String str2 = str.toString();
- return str2.startsWith(prefix.toString()) && str2.endsWith(suffix.toString());
- }
-
- /**
- * 给定字符串是否被字符包围
- *
- * @param str 字符串
- * @param prefix 前缀
- * @param suffix 后缀
- * @return 是否包围,空串不包围
- */
- public static boolean isSurround(CharSequence str, char prefix, char suffix) {
- if (StrUtil.isBlank(str)) {
- return false;
- }
- if (str.length() < 2) {
- return false;
- }
-
- return str.charAt(0) == prefix && str.charAt(str.length() - 1) == suffix;
- }
-
- /**
- * 重复某个字符
- *
- * @param c 被重复的字符
- * @param count 重复的数目,如果小于等于0则返回""
- * @return 重复字符字符串
- */
- public static String repeat(char c, int count) {
- if (count <= 0) {
- return EMPTY;
- }
-
- char[] result = new char[count];
- for (int i = 0; i < count; i++) {
- result[i] = c;
- }
- return new String(result);
- }
-
- /**
- * 重复某个字符串
- *
- * @param str 被重复的字符
- * @param count 重复的数目
- * @return 重复字符字符串
- */
- public static String repeat(CharSequence str, int count) {
- if (null == str) {
- return null;
- }
- if (count <= 0 || str.length() == 0) {
- return EMPTY;
- }
- if (count == 1) {
- return str.toString();
- }
-
- // 检查
- final int len = str.length();
- final long longSize = (long) len * (long) count;
- final int size = (int) longSize;
- if (size != longSize) {
- throw new ArrayIndexOutOfBoundsException("Required String length is too large: " + longSize);
- }
-
- final char[] array = new char[size];
- str.toString().getChars(0, len, array, 0);
- int n;
- for (n = len; n < size - n; n <<= 1) {// n <<= 1相当于n *2
- System.arraycopy(array, 0, array, n, n);
- }
- System.arraycopy(array, 0, array, n, size - n);
- return new String(array);
- }
-
- /**
- * 重复某个字符串到指定长度
- *
- * @param str 被重复的字符
- * @param padLen 指定长度
- * @return 重复字符字符串
- * @since 4.3.2
- */
- public static String repeatByLength(CharSequence str, int padLen) {
- if (null == str) {
- return null;
- }
- if (padLen <= 0) {
- return StrUtil.EMPTY;
- }
- final int strLen = str.length();
- if (strLen == padLen) {
- return str.toString();
- } else if (strLen > padLen) {
- return subPre(str, padLen);
- }
-
- // 重复,直到达到指定长度
- final char[] padding = new char[padLen];
- for (int i = 0; i < padLen; i++) {
- padding[i] = str.charAt(i % strLen);
- }
- return new String(padding);
- }
-
- /**
- * 重复某个字符串并通过分界符连接
- *
- *
- * StrUtil.repeatAndJoin("?", 5, ",") = "?,?,?,?,?"
- * StrUtil.repeatAndJoin("?", 0, ",") = ""
- * StrUtil.repeatAndJoin("?", 5, null) = "?????"
- *
- *
- * @param str 被重复的字符串
- * @param count 数量
- * @param conjunction 分界符
- * @return 连接后的字符串
- * @since 4.0.1
- */
- public static String repeatAndJoin(CharSequence str, int count, CharSequence conjunction) {
- if (count <= 0) {
- return EMPTY;
- }
- final StrBuilder builder = StrBuilder.create();
- boolean isFirst = true;
- while (count-- > 0) {
- if (isFirst) {
- isFirst = false;
- } else if (isNotEmpty(conjunction)) {
- builder.append(conjunction);
- }
- builder.append(str);
- }
- return builder.toString();
- }
-
- /**
- * 比较两个字符串(大小写敏感)。
- *
- *
- * equals(null, null) = true
- * equals(null, "abc") = false
- * equals("abc", null) = false
- * equals("abc", "abc") = true
- * equals("abc", "ABC") = false
- *
- *
- * @param str1 要比较的字符串1
- * @param str2 要比较的字符串2
- * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
- */
- public static boolean equals(CharSequence str1, CharSequence str2) {
- return equals(str1, str2, false);
- }
-
- /**
- * 比较两个字符串(大小写不敏感)。
- *
- *
- * equalsIgnoreCase(null, null) = true
- * equalsIgnoreCase(null, "abc") = false
- * equalsIgnoreCase("abc", null) = false
- * equalsIgnoreCase("abc", "abc") = true
- * equalsIgnoreCase("abc", "ABC") = true
- *
- *
- * @param str1 要比较的字符串1
- * @param str2 要比较的字符串2
- * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
- */
- public static boolean equalsIgnoreCase(CharSequence str1, CharSequence str2) {
- return equals(str1, str2, true);
- }
-
- /**
- * 比较两个字符串是否相等。
- *
- * @param str1 要比较的字符串1
- * @param str2 要比较的字符串2
- * @param ignoreCase 是否忽略大小写
- * @return 如果两个字符串相同,或者都是{@code null},则返回{@code true}
- * @since 3.2.0
- */
- public static boolean equals(CharSequence str1, CharSequence str2, boolean ignoreCase) {
- if (null == str1) {
- // 只有两个都为null才判断相等
- return str2 == null;
- }
- if (null == str2) {
- // 字符串2空,字符串1非空,直接false
- return false;
- }
-
- if (ignoreCase) {
- return str1.toString().equalsIgnoreCase(str2.toString());
- } else {
- return str1.toString().contentEquals(str2);
- }
- }
-
- /**
- * 给定字符串是否与提供的中任一字符串相同(忽略大小写),相同则返回{@code true},没有相同的返回{@code false}- * HelloWorld=》hello_world - * Hello_World=》hello_world - * HelloWorld_test=》hello_world_test - *- * - * @param str 转换前的驼峰式命名的字符串,也可以为下划线形式 - * @return 转换后下划线方式命名的字符串 - */ - public static String toUnderlineCase(CharSequence str) { - return toSymbolCase(str, CharUtil.UNDERLINE); - } - - /** - * 将驼峰式命名的字符串转换为使用符号连接方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
- * StrUtil.padPre(null, *, *);//null
- * StrUtil.padPre("1", 3, "ABC");//"AB1"
- * StrUtil.padPre("123", 2, "ABC");//"12"
- *
- *
- * @param str 字符串
- * @param minLength 最小长度
- * @param padStr 补充的字符
- * @return 补充后的字符串
- */
- public static String padPre(CharSequence str, int minLength, CharSequence padStr) {
- if (null == str) {
- return null;
- }
- final int strLen = str.length();
- if (strLen == minLength) {
- return str.toString();
- } else if (strLen > minLength) {
- return subPre(str, minLength);
- }
-
- return repeatByLength(padStr, minLength - strLen).concat(str.toString());
- }
-
- /**
- * 补充字符串以满足最小长度
- *
- *
- * StrUtil.padPre(null, *, *);//null
- * StrUtil.padPre("1", 3, '0');//"001"
- * StrUtil.padPre("123", 2, '0');//"12"
- *
- *
- * @param str 字符串
- * @param minLength 最小长度
- * @param padChar 补充的字符
- * @return 补充后的字符串
- */
- public static String padPre(CharSequence str, int minLength, char padChar) {
- if (null == str) {
- return null;
- }
- final int strLen = str.length();
- if (strLen == minLength) {
- return str.toString();
- } else if (strLen > minLength) {
- return subPre(str, minLength);
- }
-
- return repeat(padChar, minLength - strLen).concat(str.toString());
- }
-
- /**
- * 补充字符串以满足最小长度
- *
- *
- * StrUtil.padAfter(null, *, *);//null
- * StrUtil.padAfter("1", 3, '0');//"100"
- * StrUtil.padAfter("123", 2, '0');//"23"
- *
- *
- * @param str 字符串,如果为{@code null},直接返回null
- * @param minLength 最小长度
- * @param padChar 补充的字符
- * @return 补充后的字符串
- */
- public static String padAfter(CharSequence str, int minLength, char padChar) {
- if (null == str) {
- return null;
- }
- final int strLen = str.length();
- if (strLen == minLength) {
- return str.toString();
- } else if (strLen > minLength) {
- return sub(str, strLen - minLength, strLen);
- }
-
- return str.toString().concat(repeat(padChar, minLength - strLen));
- }
-
- /**
- * 补充字符串以满足最小长度
- *
- *
- * StrUtil.padAfter(null, *, *);//null
- * StrUtil.padAfter("1", 3, "ABC");//"1AB"
- * StrUtil.padAfter("123", 2, "ABC");//"23"
- *
- *
- * @param str 字符串,如果为{@code null},直接返回null
- * @param minLength 最小长度
- * @param padStr 补充的字符
- * @return 补充后的字符串
- * @since 4.3.2
- */
- public static String padAfter(CharSequence str, int minLength, CharSequence padStr) {
- if (null == str) {
- return null;
- }
- final int strLen = str.length();
- if (strLen == minLength) {
- return str.toString();
- } else if (strLen > minLength) {
- return subSufByLength(str, minLength);
- }
-
- return str.toString().concat(repeatByLength(padStr, minLength - strLen));
- }
-
- /**
- * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
- *
- *
- * StrUtil.center(null, *) = null
- * StrUtil.center("", 4) = " "
- * StrUtil.center("ab", -1) = "ab"
- * StrUtil.center("ab", 4) = " ab "
- * StrUtil.center("abcd", 2) = "abcd"
- * StrUtil.center("a", 4) = " a "
- *
- *
- * @param str 字符串
- * @param size 指定长度
- * @return 补充后的字符串
- * @since 4.3.2
- */
- public static String center(CharSequence str, final int size) {
- return center(str, size, CharUtil.SPACE);
- }
-
- /**
- * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
- *
- *
- * StrUtil.center(null, *, *) = null
- * StrUtil.center("", 4, ' ') = " "
- * StrUtil.center("ab", -1, ' ') = "ab"
- * StrUtil.center("ab", 4, ' ') = " ab "
- * StrUtil.center("abcd", 2, ' ') = "abcd"
- * StrUtil.center("a", 4, ' ') = " a "
- * StrUtil.center("a", 4, 'y') = "yayy"
- * StrUtil.center("abc", 7, ' ') = " abc "
- *
- *
- * @param str 字符串
- * @param size 指定长度
- * @param padChar 两边补充的字符
- * @return 补充后的字符串
- * @since 4.3.2
- */
- public static String center(CharSequence str, final int size, char padChar) {
- if (str == null || size <= 0) {
- return str(str);
- }
- final int strLen = str.length();
- final int pads = size - strLen;
- if (pads <= 0) {
- return str.toString();
- }
- str = padPre(str, strLen + pads / 2, padChar);
- str = padAfter(str, size, padChar);
- return str.toString();
- }
-
- /**
- * 居中字符串,两边补充指定字符串,如果指定长度小于字符串,则返回原字符串
- *
- *
- * StrUtil.center(null, *, *) = null
- * StrUtil.center("", 4, " ") = " "
- * StrUtil.center("ab", -1, " ") = "ab"
- * StrUtil.center("ab", 4, " ") = " ab "
- * StrUtil.center("abcd", 2, " ") = "abcd"
- * StrUtil.center("a", 4, " ") = " a "
- * StrUtil.center("a", 4, "yz") = "yayz"
- * StrUtil.center("abc", 7, null) = " abc "
- * StrUtil.center("abc", 7, "") = " abc "
- *
- *
- * @param str 字符串
- * @param size 指定长度
- * @param padStr 两边补充的字符串
- * @return 补充后的字符串
- */
- public static String center(CharSequence str, final int size, CharSequence padStr) {
- if (str == null || size <= 0) {
- return str(str);
- }
- if (isEmpty(padStr)) {
- padStr = SPACE;
- }
- final int strLen = str.length();
- final int pads = size - strLen;
- if (pads <= 0) {
- return str.toString();
- }
- str = padPre(str, strLen + pads / 2, padStr);
- str = padAfter(str, size, padStr);
- return str.toString();
- }
-
/**
* 创建StringBuilder对象
*
@@ -3609,30 +507,6 @@ public class StrUtil {
return StrBuilder.create(capacity);
}
- /**
- * 创建StringBuilder对象
- *
- * @param strs 初始字符串列表
- * @return StringBuilder对象
- */
- public static StringBuilder builder(CharSequence... strs) {
- final StringBuilder sb = new StringBuilder();
- for (CharSequence str : strs) {
- sb.append(str);
- }
- return sb;
- }
-
- /**
- * 创建StrBuilder对象
- *
- * @param strs 初始字符串列表
- * @return StrBuilder对象
- */
- public static StrBuilder strBuilder(CharSequence... strs) {
- return StrBuilder.create(strs);
- }
-
/**
* 获得StringReader
*
@@ -3655,566 +529,6 @@ public class StrUtil {
return new StringWriter();
}
- /**
- * 统计指定内容中包含指定字符串的数量
- * StrUtil.count(null, *) = 0
- * StrUtil.count("", *) = 0
- * StrUtil.count("abba", null) = 0
- * StrUtil.count("abba", "") = 0
- * StrUtil.count("abba", "a") = 2
- * StrUtil.count("abba", "ab") = 1
- * StrUtil.count("abba", "xxx") = 0
- *
- *
- * @param content 被查找的字符串
- * @param strForSearch 需要查找的字符串
- * @return 查找到的个数
- */
- public static int count(CharSequence content, CharSequence strForSearch) {
- if (hasEmpty(content, strForSearch) || strForSearch.length() > content.length()) {
- return 0;
- }
-
- int count = 0;
- int idx = 0;
- final String content2 = content.toString();
- final String strForSearch2 = strForSearch.toString();
- while ((idx = content2.indexOf(strForSearch2, idx)) > -1) {
- count++;
- idx += strForSearch.length();
- }
- return count;
- }
-
- /**
- * 统计指定内容中包含指定字符的数量
- *
- * @param content 内容
- * @param charForSearch 被统计的字符
- * @return 包含数量
- */
- public static int count(CharSequence content, char charForSearch) {
- int count = 0;
- if (isEmpty(content)) {
- return 0;
- }
- int contentLength = content.length();
- for (int i = 0; i < contentLength; i++) {
- if (charForSearch == content.charAt(i)) {
- count++;
- }
- }
- return count;
- }
-
- /**
- * 将字符串切分为N等份
- *
- * @param str 字符串
- * @param partLength 每等份的长度
- * @return 切分后的数组
- * @since 3.0.6
- */
- public static String[] cut(CharSequence str, int partLength) {
- if (null == str) {
- return null;
- }
- int len = str.length();
- if (len < partLength) {
- return new String[]{str.toString()};
- }
- int part = NumberUtil.count(len, partLength);
- final String[] array = new String[part];
-
- final String str2 = str.toString();
- for (int i = 0; i < part; i++) {
- array[i] = str2.substring(i * partLength, (i == part - 1) ? len : (partLength + i * partLength));
- }
- return array;
- }
-
- /**
- * 将给定字符串,变成 "xxx...xxx" 形式的字符串
- *
- * @param str 字符串
- * @param maxLength 最大长度
- * @return 截取后的字符串
- */
- public static String brief(CharSequence str, int maxLength) {
- if (null == str) {
- return null;
- }
- if (str.length() <= maxLength) {
- return str.toString();
- }
- int w = maxLength / 2;
- int l = str.length() + 3;
-
- final String str2 = str.toString();
- return format("{}...{}", str2.substring(0, maxLength - w), str2.substring(l - w));
- }
-
- /**
- * 比较两个字符串,用于排序
- *
- *
- * StrUtil.compare(null, null, *) = 0
- * StrUtil.compare(null , "a", true) < 0
- * StrUtil.compare(null , "a", false) > 0
- * StrUtil.compare("a", null, true) > 0
- * StrUtil.compare("a", null, false) < 0
- * StrUtil.compare("abc", "abc", *) = 0
- * StrUtil.compare("a", "b", *) < 0
- * StrUtil.compare("b", "a", *) > 0
- * StrUtil.compare("a", "B", *) > 0
- * StrUtil.compare("ab", "abc", *) < 0
- *
- *
- * @param str1 字符串1
- * @param str2 字符串2
- * @param nullIsLess {@code null} 值是否排在前(null是否小于非空值)
- * @return 排序值。负数:str1 < str2,正数:str1 > str2, 0:str1 == str2
- */
- public static int compare(final CharSequence str1, final CharSequence str2, final boolean nullIsLess) {
- if (str1 == str2) {
- return 0;
- }
- if (str1 == null) {
- return nullIsLess ? -1 : 1;
- }
- if (str2 == null) {
- return nullIsLess ? 1 : -1;
- }
- return str1.toString().compareTo(str2.toString());
- }
-
- /**
- * 比较两个字符串,用于排序,大小写不敏感
- *
- *
- * StrUtil.compareIgnoreCase(null, null, *) = 0
- * StrUtil.compareIgnoreCase(null , "a", true) < 0
- * StrUtil.compareIgnoreCase(null , "a", false) > 0
- * StrUtil.compareIgnoreCase("a", null, true) > 0
- * StrUtil.compareIgnoreCase("a", null, false) < 0
- * StrUtil.compareIgnoreCase("abc", "abc", *) = 0
- * StrUtil.compareIgnoreCase("abc", "ABC", *) = 0
- * StrUtil.compareIgnoreCase("a", "b", *) < 0
- * StrUtil.compareIgnoreCase("b", "a", *) > 0
- * StrUtil.compareIgnoreCase("a", "B", *) < 0
- * StrUtil.compareIgnoreCase("A", "b", *) < 0
- * StrUtil.compareIgnoreCase("ab", "abc", *) < 0
- *
- *
- * @param str1 字符串1
- * @param str2 字符串2
- * @param nullIsLess {@code null} 值是否排在前(null是否小于非空值)
- * @return 排序值。负数:str1 < str2,正数:str1 > str2, 0:str1 == str2
- */
- public static int compareIgnoreCase(CharSequence str1, CharSequence str2, boolean nullIsLess) {
- if (str1 == str2) {
- return 0;
- }
- if (str1 == null) {
- return nullIsLess ? -1 : 1;
- }
- if (str2 == null) {
- return nullIsLess ? 1 : -1;
- }
- return str1.toString().compareToIgnoreCase(str2.toString());
- }
-
- /**
- * 比较两个版本
- * StrUtil.compareVersion(null, "v1") < 0
- * StrUtil.compareVersion("v1", "v1") = 0
- * StrUtil.compareVersion(null, null) = 0
- * StrUtil.compareVersion("v1", null) > 0
- * StrUtil.compareVersion("1.0.0", "1.0.2") < 0
- * StrUtil.compareVersion("1.0.2", "1.0.2a") < 0
- * StrUtil.compareVersion("1.13.0", "1.12.1c") > 0
- * StrUtil.compareVersion("V0.0.20170102", "V0.0.20170101") > 0
- *
- *
- * @param version1 版本1
- * @param version2 版本2
- * @return 排序值。负数:version1 < version2,正数:version1 > version2, 0:version1 == version2
- * @since 4.0.2
- */
- public static int compareVersion(CharSequence version1, CharSequence version2) {
- return VersionComparator.INSTANCE.compare(str(version1), str(version2));
- }
-
- /**
- * 指定范围内查找指定字符
- *
- * @param str 字符串
- * @param searchChar 被查找的字符
- * @return 位置
- */
- public static int indexOf(final CharSequence str, char searchChar) {
- return indexOf(str, searchChar, 0);
- }
-
- /**
- * 指定范围内查找指定字符
- *
- * @param str 字符串
- * @param searchChar 被查找的字符
- * @param start 起始位置,如果小于0,从0开始查找
- * @return 位置
- */
- public static int indexOf(CharSequence str, char searchChar, int start) {
- if (str instanceof String) {
- return ((String) str).indexOf(searchChar, start);
- } else {
- return indexOf(str, searchChar, start, -1);
- }
- }
-
- /**
- * 指定范围内查找指定字符
- *
- * @param str 字符串
- * @param searchChar 被查找的字符
- * @param start 起始位置,如果小于0,从0开始查找
- * @param end 终止位置,如果超过str.length()则默认查找到字符串末尾
- * @return 位置
- */
- public static int indexOf(final CharSequence str, char searchChar, int start, int end) {
- if (isEmpty(str)) {
- return INDEX_NOT_FOUND;
- }
- final int len = str.length();
- if (start < 0 || start > len) {
- start = 0;
- }
- if (end > len || end < 0) {
- end = len;
- }
- for (int i = start; i < end; i++) {
- if (str.charAt(i) == searchChar) {
- return i;
- }
- }
- return INDEX_NOT_FOUND;
- }
-
- /**
- * 指定范围内查找字符串,忽略大小写
- * StrUtil.indexOfIgnoreCase(null, *, *) = -1
- * StrUtil.indexOfIgnoreCase(*, null, *) = -1
- * StrUtil.indexOfIgnoreCase("", "", 0) = 0
- * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
- * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
- * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
- * StrUtil.indexOfIgnoreCase("abc", "", 9) = -1
- *
- *
- * @param str 字符串
- * @param searchStr 需要查找位置的字符串
- * @return 位置
- * @since 3.2.1
- */
- public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
- return indexOfIgnoreCase(str, searchStr, 0);
- }
-
- /**
- * 指定范围内查找字符串
- *
- *
- * StrUtil.indexOfIgnoreCase(null, *, *) = -1
- * StrUtil.indexOfIgnoreCase(*, null, *) = -1
- * StrUtil.indexOfIgnoreCase("", "", 0) = 0
- * StrUtil.indexOfIgnoreCase("aabaabaa", "A", 0) = 0
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 0) = 2
- * StrUtil.indexOfIgnoreCase("aabaabaa", "AB", 0) = 1
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 3) = 5
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", 9) = -1
- * StrUtil.indexOfIgnoreCase("aabaabaa", "B", -1) = 2
- * StrUtil.indexOfIgnoreCase("aabaabaa", "", 2) = 2
- * StrUtil.indexOfIgnoreCase("abc", "", 9) = -1
- *
- *
- * @param str 字符串
- * @param searchStr 需要查找位置的字符串
- * @param fromIndex 起始位置
- * @return 位置
- * @since 3.2.1
- */
- public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr, int fromIndex) {
- return indexOf(str, searchStr, fromIndex, true);
- }
-
- /**
- * 指定范围内查找字符串
- *
- * @param str 字符串
- * @param searchStr 需要查找位置的字符串
- * @param fromIndex 起始位置
- * @param ignoreCase 是否忽略大小写
- * @return 位置
- * @since 3.2.1
- */
- public static int indexOf(final CharSequence str, CharSequence searchStr, int fromIndex, boolean ignoreCase) {
- if (str == null || searchStr == null) {
- return INDEX_NOT_FOUND;
- }
- if (fromIndex < 0) {
- fromIndex = 0;
- }
-
- final int endLimit = str.length() - searchStr.length() + 1;
- if (fromIndex > endLimit) {
- return INDEX_NOT_FOUND;
- }
- if (searchStr.length() == 0) {
- return fromIndex;
- }
-
- if (false == ignoreCase) {
- // 不忽略大小写调用JDK方法
- return str.toString().indexOf(searchStr.toString(), fromIndex);
- }
-
- for (int i = fromIndex; i < endLimit; i++) {
- if (isSubEquals(str, i, searchStr, 0, searchStr.length(), true)) {
- return i;
- }
- }
- return INDEX_NOT_FOUND;
- }
-
- /**
- * 指定范围内查找字符串,忽略大小写
- *
- * @param str 字符串
- * @param searchStr 需要查找位置的字符串
- * @return 位置
- * @since 3.2.1
- */
- public static int lastIndexOfIgnoreCase(final CharSequence str, final CharSequence searchStr) {
- return lastIndexOfIgnoreCase(str, searchStr, str.length());
- }
-
- /**
- * 指定范围内查找字符串,忽略大小写
- * 如果 str=null 或 searchStr=null 或 ordinal≥0 则返回-1
- * 此方法来自:Apache-Commons-Lang
- *
- * 例子(*代表任意字符): - * - *
- * StrUtil.ordinalIndexOf(null, *, *) = -1
- * StrUtil.ordinalIndexOf(*, null, *) = -1
- * StrUtil.ordinalIndexOf("", "", *) = 0
- * StrUtil.ordinalIndexOf("aabaabaa", "a", 1) = 0
- * StrUtil.ordinalIndexOf("aabaabaa", "a", 2) = 1
- * StrUtil.ordinalIndexOf("aabaabaa", "b", 1) = 2
- * StrUtil.ordinalIndexOf("aabaabaa", "b", 2) = 5
- * StrUtil.ordinalIndexOf("aabaabaa", "ab", 1) = 1
- * StrUtil.ordinalIndexOf("aabaabaa", "ab", 2) = 4
- * StrUtil.ordinalIndexOf("aabaabaa", "", 1) = 0
- * StrUtil.ordinalIndexOf("aabaabaa", "", 2) = 0
- *
- *
- * @param str 被检查的字符串,可以为null
- * @param searchStr 被查找的字符串,可以为null
- * @param ordinal 第几次出现的位置
- * @return 查找到的位置
- * @since 3.2.3
- */
- public static int ordinalIndexOf(String str, String searchStr, int ordinal) {
- if (str == null || searchStr == null || ordinal <= 0) {
- return INDEX_NOT_FOUND;
- }
- if (searchStr.length() == 0) {
- return 0;
- }
- int found = 0;
- int index = INDEX_NOT_FOUND;
- do {
- index = str.indexOf(searchStr, index + 1);
- if (index < 0) {
- return index;
- }
- found++;
- } while (found < ordinal);
- return index;
- }
-
- // ------------------------------------------------------------------------------------------------------------------ Append and prepend
-
- /**
- * 如果给定字符串不是以给定的一个或多个字符串为结尾,则在尾部添加结尾字符串- * 1. 大写字母包括A-Z - * 2. 其它非字母的Unicode符都算作大写 - *- * - * @param str 被检查的字符串 - * @return 是否全部为大写 - * @since 4.2.2 + * @param template 文本模板,被替换的部分用 {key} 表示 + * @param map 参数值对 + * @param ignoreNull 是否忽略 {@code null} 值,忽略则 {@code null} 值对应的变量不被替换,否则替换为"" + * @return 格式化后的文本 + * @since 5.4.3 */ - public static boolean isUpperCase(CharSequence str) { - if (null == str) { - return false; + public static String format(CharSequence template, Map, ?> map, boolean ignoreNull) { + if (null == template) { + return null; } - final int len = str.length(); - for (int i = 0; i < len; i++) { - if (Character.isLowerCase(str.charAt(i))) { - return false; + if (null == map || map.isEmpty()) { + return template.toString(); + } + + String template2 = template.toString(); + String value; + for (Map.Entry, ?> entry : map.entrySet()) { + value = utf8Str(entry.getValue()); + if (null == value && ignoreNull) { + continue; } + template2 = replace(template2, "{" + entry.getKey() + "}", value); } - return true; - } - - /** - * 给定字符串中的字母是否全部为小写,判断依据如下: - * - *
- * 1. 小写字母包括a-z - * 2. 其它非字母的Unicode符都算作小写 - *- * - * @param str 被检查的字符串 - * @return 是否全部为小写 - * @since 4.2.2 - */ - public static boolean isLowerCase(CharSequence str) { - if (null == str) { - return false; - } - final int len = str.length(); - for (int i = 0; i < len; i++) { - if (Character.isUpperCase(str.charAt(i))) { - return false; - } - } - return true; - } - - /** - * 获取字符串的长度,如果为null返回0 - * - * @param cs a 字符串 - * @return 字符串的长度,如果为null返回0 - * @since 4.3.2 - */ - public static int length(CharSequence cs) { - return cs == null ? 0 : cs.length(); - } - - /** - * 给定字符串转为bytes后的byte数(byte长度) - * - * @param cs 字符串 - * @param charset 编码 - * @return byte长度 - * @since 4.5.2 - */ - public static int byteLength(CharSequence cs, Charset charset) { - return cs == null ? 0 : cs.toString().getBytes(charset).length; - } - - /** - * 切换给定字符串中的大小写。大写转小写,小写转大写。 - * - *
- * StrUtil.swapCase(null) = null
- * StrUtil.swapCase("") = ""
- * StrUtil.swapCase("The dog has a BONE") = "tHE DOG HAS A bone"
- *
- *
- * @param str 字符串
- * @return 交换后的字符串
- * @since 4.3.2
- */
- public static String swapCase(final String str) {
- if (isEmpty(str)) {
- return str;
- }
-
- final char[] buffer = str.toCharArray();
-
- for (int i = 0; i < buffer.length; i++) {
- final char ch = buffer[i];
- if (Character.isUpperCase(ch)) {
- buffer[i] = Character.toLowerCase(ch);
- } else if (Character.isTitleCase(ch)) {
- buffer[i] = Character.toLowerCase(ch);
- } else if (Character.isLowerCase(ch)) {
- buffer[i] = Character.toUpperCase(ch);
- }
- }
- return new String(buffer);
- }
-
- /**
- * 过滤字符串
- *
- * @param str 字符串
- * @param filter 过滤器
- * @return 过滤后的字符串
- * @since 5.4.0
- */
- public static String filter(CharSequence str, final Filter