org.memoeslink.StringHelper Maven / Gradle / Ivy
Show all versions of helper Show documentation
package org.memoeslink;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.Normalizer;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StringHelper {
public static final int INDEX_NOT_FOUND = -1;
public static final String EMPTY = "";
public static final String DEFAULT_VALUE = "?";
private StringHelper() {
}
/**
* Checks if the given string is {@code null} or empty.
*
* @param s the string to check
* @return {@code true} if the string is {@code null} or its length is 0, {@code false} otherwise
*/
public static boolean isNullOrEmpty(String s) {
return s == null || s.isEmpty();
}
/**
* Checks if the given string is not {@code null} and not empty.
*
* @param s the string to check
* @return {@code true} if the string is not {@code null} and its length is greater than 0, {@code false} otherwise
*/
public static boolean isNotNullOrEmpty(String s) {
return !isNullOrEmpty(s);
}
/**
* Checks if the given string is {@code null} or contains only whitespace characters.
*
* @param s the string to check
* @return {@code true} if the string is {@code null} or blank, {@code false} otherwise
*/
public static boolean isNullOrBlank(String s) {
return s == null || s.isBlank();
}
/**
* Checks if the given string is not {@code null} and contains at least one non-whitespace character.
*
* @param s the string to check
* @return {@code true} if the string is not {@code null} and not blank, {@code false} otherwise
*/
public static boolean isNotNullOrBlank(String s) {
return !isNullOrBlank(s);
}
/**
* Returns the index within the given string of the first occurrence of the specified character.
*
* @param s the string to search
* @param c the character to find
* @return the index of the first occurrence of the character in the string, or {@value #INDEX_NOT_FOUND} if the character does not occur
*/
public static int indexOf(String s, char c) {
return indexOf(s, String.valueOf(c));
}
/**
* Returns the index within the given string of the first occurrence of the specified substring.
*
* @param s the string to search
* @param occurrence the substring to find
* @return the index of the first occurrence of the substring in the string, or {@value #INDEX_NOT_FOUND} if the substring does not occur
*/
public static int indexOf(String s, String occurrence) {
if (isNullOrEmpty(s)) return INDEX_NOT_FOUND;
return s.indexOf(occurrence);
}
/**
* Returns a default value if the given string is {@code null}, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not {@code null}, otherwise {@value #DEFAULT_VALUE}
*/
public static String defaultOnNull(String s) {
return defaultIfNull(s, DEFAULT_VALUE);
}
/**
* Returns an empty string if the given string is {@code null}, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not {@code null}, otherwise an empty string
*/
public static String defaultIfNull(String s) {
return defaultIfNull(s, EMPTY);
}
/**
* Returns the default value if the given string is {@code null}, otherwise returns the string itself.
*
* @param s the string to check
* @param defaultValue the default value to return if {@code s} is {@code null}
* @return the original string if it is not {@code null}, otherwise the specified default value
*/
public static String defaultIfNull(String s, String defaultValue) {
if (s == null) return defaultValue == null ? EMPTY : defaultValue;
return s;
}
/**
* Returns a default value if the given string is empty, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not empty, otherwise {@value #DEFAULT_VALUE}
*/
public static String defaultOnEmpty(String s) {
return defaultIfEmpty(s, DEFAULT_VALUE);
}
/**
* Returns an empty string if the given string is empty, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not empty, otherwise an empty string
*/
public static String defaultIfEmpty(String s) {
return defaultIfEmpty(s, EMPTY);
}
/**
* Returns the default value if the given string is empty, otherwise returns the string itself.
*
* @param s the string to check
* @param defaultValue the default value to return if {@code s} is empty
* @return the original string if it is not empty, otherwise the specified default value
*/
public static String defaultIfEmpty(String s, String defaultValue) {
if (isNullOrEmpty(s)) return defaultValue == null ? EMPTY : defaultValue;
return s;
}
/**
* Returns a default value if the given string is blank, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not blank, otherwise {@value #DEFAULT_VALUE}
*/
public static String defaultOnBlank(String s) {
return defaultIfBlank(s, DEFAULT_VALUE);
}
/**
* Returns an empty string if the given string is blank, otherwise returns the string itself.
*
* @param s the string to check
* @return the original string if it is not blank, otherwise an empty string
*/
public static String defaultIfBlank(String s) {
return defaultIfBlank(s, EMPTY);
}
/**
* Returns the default value if the given string is blank, otherwise returns the string itself.
*
* @param s the string to check
* @param defaultValue the default value to return if {@code s} is blank
* @return the original string if it is not blank, otherwise the specified default value
*/
public static String defaultIfBlank(String s, String defaultValue) {
if (isNullOrBlank(s)) return defaultValue == null ? EMPTY : defaultValue;
return s;
}
/**
* Returns the first non-null string from the given array, or the default value if all are {@code null}.
*
* @param strings the array of strings to check
* @return the first non-null string, or the specified default value if all strings are {@code null}
*/
public static String getFirstNonNull(String... strings) {
return getFirstNonNullOrDefault(null, strings);
}
/**
* Returns the first string that is not {@code null} or empty from the given array, or the default value if all are {@code null} or empty.
*
* @param strings the array of strings to check
* @return the first string that is not {@code null} or empty, or the specified default value if all strings are {@code null} or empty
*/
public static String getFirstNonEmpty(String... strings) {
return getFirstNonEmptyOrDefault(null, strings);
}
/**
* Returns the first string that is not {@code null} or blank from the given array, or the default value if all are {@code null} or blank.
*
* @param strings the array of strings to check
* @return the first string that is not {@code null} or blank, or the specified default value if all strings are {@code null} or blank
*/
public static String getFirstNonBlank(String... strings) {
return getFirstNonBlankOrDefault(null, strings);
}
/**
* Returns the first non-null string from the given array, or the specified default value if all are {@code null}.
*
* @param defaultValue the default value to return if all strings are {@code null}
* @param strings the array of strings to check
* @return the first non-null string, or the specified default value if all strings are {@code null}
*/
public static String getFirstNonNullOrDefault(String defaultValue, String... strings) {
for (String s : strings) {
if (s != null) return s;
}
return defaultValue;
}
/**
* Returns the first string that is not {@code null} or empty from the given array, or the specified default value if all are {@code null} or empty.
*
* @param defaultValue the default value to return if all strings are {@code null} or empty
* @param strings the array of strings to check
* @return the first string that is not {@code null} or empty, or the specified default value if all strings are {@code null} or empty
*/
public static String getFirstNonEmptyOrDefault(String defaultValue, String... strings) {
for (String s : strings) {
if (isNotNullOrEmpty(s)) return s;
}
return defaultValue;
}
/**
* Returns the first string that is not {@code null} or blank from the given array, or the specified default value if all are {@code null} or blank.
*
* @param defaultValue the default value to return if all strings are {@code null} or blank
* @param strings the array of strings to check
* @return the first string that is not {@code null} or blank, or the specified default value if all strings are {@code null} or blank
*/
public static String getFirstNonBlankOrDefault(String defaultValue, String... strings) {
for (String s : strings) {
if (isNotNullOrBlank(s)) return s;
}
return defaultValue;
}
/**
* Returns the first string from the given array that is not {@code null}; otherwise, returns a default value.
*
* @param strings the array of strings to check
* @return the first non-null string from the array, or {@value #DEFAULT_VALUE} if all strings are {@code null}
*/
public static String getFirstNonNullElseDefault(String... strings) {
return getFirstNonNullOrDefault(DEFAULT_VALUE, strings);
}
/**
* Returns the first string from the given array that is not {@code null} or empty; otherwise, returns a default value.
*
* @param strings the array of strings to check
* @return the first non-empty string from the array, or {@value #DEFAULT_VALUE} if all strings are {@code null} or empty
*/
public static String getFirstNonEmptyElseDefault(String... strings) {
return getFirstNonEmptyOrDefault(DEFAULT_VALUE, strings);
}
/**
* Returns the first string from the given array that is not {@code null} or blank; otherwise, returns a default value.
*
* @param strings the array of strings to check
* @return the first non-blank string from the array, or {@value #DEFAULT_VALUE} if all strings are {@code null} or blank
*/
public static String getFirstNonBlankElseDefault(String... strings) {
return getFirstNonBlankOrDefault(DEFAULT_VALUE, strings);
}
/**
* Prepends the given prefix to the string if the string is not {@code null}.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @return the string with the prefix prepended if the string is not {@code null}; otherwise, {@code null}
*/
public static String prependIfNotNull(String s, String prefix) {
return prependIfNotNull(s, prefix, EMPTY);
}
/**
* Prepends the given prefix to the string if the string is not {@code null}, using a default prefix if the given prefix is {@code null}.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @return the string with the prefix or default prefix prepended if the string is not {@code null}; otherwise, {@code null}
*/
public static String prependIfNotNull(String s, String prefix, String defaultPrefix) {
if (s == null) return null;
return defaultIfNull(prefix, defaultPrefix) + s;
}
/**
* Prepends the given prefix to the string if the string is not {@code null} or empty.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @return the string with the prefix prepended if the string is not {@code null} or empty; otherwise, returns the original string
*/
public static String prependIfNotEmpty(String s, String prefix) {
return prependIfNotEmpty(s, prefix, EMPTY);
}
/**
* Prepends the given prefix to the string if the string is not {@code null} or empty, using a default prefix if the given prefix is {@code null}.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @return the string with the prefix or default prefix prepended if the string is not {@code null} or empty; otherwise, returns the original string
*/
public static String prependIfNotEmpty(String s, String prefix, String defaultPrefix) {
if (isNullOrEmpty(s)) return s;
return defaultIfNull(prefix, defaultPrefix) + s;
}
/**
* Prepends the given prefix to the string if the string is not {@code null} or blank.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @return the string with the prefix prepended if the string is not {@code null} or blank; otherwise, returns the original string
*/
public static String prependIfNotBlank(String s, String prefix) {
return prependIfNotBlank(s, prefix, EMPTY);
}
/**
* Prepends the given prefix to the string if the string is not {@code null} or blank, using a default prefix if the given prefix is {@code null}.
*
* @param s the string to prepend to
* @param prefix the prefix to prepend
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @return the string with the prefix or default prefix prepended if the string is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String prependIfNotBlank(String s, String prefix, String defaultPrefix) {
if (isNullOrBlank(s)) return s;
return defaultIfNull(prefix, defaultPrefix) + s;
}
/**
* Prepends a space to the specified string if the string is not {@code null}.
*
* @param s the string to prepend to
* @return the modified string with a leading space if {@code s} is not {@code null}; otherwise, returns {@code null}
*/
public static String prependSpaceIfNotNull(String s) {
return prependIfNotNull(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Prepends a space to the specified string if the string is not {@code null} or empty.
*
* @param s the string to prepend to
* @return the modified string with a leading space if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String prependSpaceIfNotEmpty(String s) {
return prependIfNotEmpty(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Prepends a space to the specified string if the string is not {@code null} or blank.
*
* @param s the string to prepend to
* @return the modified string with a leading space if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String prependSpaceIfNotBlank(String s) {
return prependIfNotBlank(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Prepends a hyphen to the specified string if the string is not {@code null}.
*
* @param s the string to prepend to
* @return the modified string with a leading hyphen if {@code s} is not {@code null}; otherwise, returns {@code null}
*/
public static String prependHyphenIfNotNull(String s) {
return prependIfNotNull(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Prepends a hyphen to the specified string if the string is not {@code null} or empty.
*
* @param s the string to prepend to
* @return the modified string with a leading hyphen if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String prependHyphenIfNotEmpty(String s) {
return prependIfNotEmpty(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Prepends a hyphen to the specified string if the string is not {@code null} or blank.
*
* @param s the string to prepend to
* @return the modified string with a leading hyphen if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String prependHyphenIfNotBlank(String s) {
return prependIfNotBlank(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Prepends a line break to the specified string if the string is not {@code null}. Uses the system's line separator
* as defined by the system property {@code "line.separator"}.
*
* @param s the string to prepend to
* @return the modified string with a leading line break if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String prependLineBreakIfNotNull(String s) {
return prependIfNotNull(s, System.lineSeparator());
}
/**
* Prepends a line break to the specified string if the string is not {@code null} or empty.
* Uses the system's line separator as defined by the system property {@code "line.separator"}.
*
* @param s the string to prepend to
* @return the modified string with a leading line break if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String prependLineBreakIfNotEmpty(String s) {
return prependIfNotEmpty(s, System.lineSeparator());
}
/**
* Prepends a line break to the specified string if the string is not {@code null} or blank.
* Uses the system's line separator as defined by the system property {@code "line.separator"}.
*
* @param s the string to prepend to
* @return the modified string with a leading line break if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String prependLineBreakIfNotBlank(String s) {
return prependIfNotBlank(s, System.lineSeparator());
}
/**
* Appends the given suffix to the string if the string is not {@code null}.
*
* @param s the string to append to
* @param suffix the suffix to append
* @return the modified string with the suffix appended if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String appendIfNotNull(String s, String suffix) {
return appendIfNotNull(s, suffix, EMPTY);
}
/**
* Appends the given suffix to the string if the string is not {@code null}, using a default suffix if the given suffix is {@code null}.
*
* @param s the string to append to
* @param suffix the suffix to append
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the string with the suffix or default suffix appended if the string is not {@code null};
* otherwise, returns {@code null}
*/
public static String appendIfNotNull(String s, String suffix, String defaultSuffix) {
if (s == null) return null;
return s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Appends the given suffix to the string if the string is not {@code null} or empty.
*
* @param s the string to append to
* @param suffix the suffix to append
* @return the modified string with the suffix appended if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String appendIfNotEmpty(String s, String suffix) {
return appendIfNotEmpty(s, suffix, EMPTY);
}
/**
* Appends the given suffix to the string if the string is not {@code null} or empty, using a default suffix
* if the given suffix is {@code null}.
*
* @param s the string to append to
* @param suffix the suffix to append
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the string with the suffix or default suffix appended if the string is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String appendIfNotEmpty(String s, String suffix, String defaultSuffix) {
if (isNullOrEmpty(s)) return s;
return s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Appends the given suffix to the string if the string is not {@code null} or blank.
*
* @param s the string to append to
* @param suffix the suffix to append
* @return the modified string with the suffix appended if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String appendIfNotBlank(String s, String suffix) {
return appendIfNotBlank(s, suffix, EMPTY);
}
/**
* Appends the given suffix to the string if the string is not {@code null} or blank, using a default suffix
* if the given suffix is {@code null}.
*
* @param s the string to append to
* @param suffix the suffix to append
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the string with the suffix or default suffix appended if the string is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String appendIfNotBlank(String s, String suffix, String defaultSuffix) {
if (isNullOrBlank(s)) return s;
return s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Appends a space to the specified string if the string is not {@code null}.
*
* @param s the string to append to
* @return the modified string with a trailing space if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String appendSpaceIfNotNull(String s) {
return appendIfNotNull(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Appends a space to the specified string if the string is not {@code null} or empty.
*
* @param s the string to append to
* @return the modified string with a trailing space if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String appendSpaceIfNotEmpty(String s) {
return appendIfNotEmpty(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Appends a space to the specified string if the string is not {@code null} or blank.
*
* @param s the string to append to
* @return the modified string with a trailing space if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String appendSpaceIfNotBlank(String s) {
return appendIfNotBlank(s, String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Appends a hyphen to the specified string if the string is not {@code null}.
*
* @param s the string to append to
* @return the modified string with a trailing hyphen if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String appendHyphenIfNotNull(String s) {
return appendIfNotNull(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Appends a hyphen to the specified string if the string is not {@code null} or empty.
*
* @param s the string to append to
* @return the modified string with a trailing hyphen if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String appendHyphenIfNotEmpty(String s) {
return appendIfNotEmpty(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Appends a hyphen to the specified string if the string is not {@code null} or blank.
*
* @param s the string to append to
* @return the modified string with a trailing hyphen if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String appendHyphenIfNotBlank(String s) {
return appendIfNotBlank(s, String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Appends a line break to the specified string if the string is not {@code null}.
* Uses the system's line separator as defined by the system property {@code "line.separator"}.
*
* @param s the string to append to
* @return the modified string with a trailing line break if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String appendLineBreakIfNotNull(String s) {
return appendIfNotNull(s, System.lineSeparator());
}
/**
* Appends a line break to the specified string if the string is not {@code null} or empty.
* Uses the system's line separator as defined by the system property {@code "line.separator"}.
*
* @param s the string to append to
* @return the modified string with a trailing line break if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String appendLineBreakIfNotEmpty(String s) {
return appendIfNotEmpty(s, System.lineSeparator());
}
/**
* Appends a line break to the specified string if the string is not {@code null} or blank.
* Uses the system's line separator as defined by the system property {@code "line.separator"}.
*
* @param s the string to append to
* @return the modified string with a trailing line break if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String appendLineBreakIfNotBlank(String s) {
return appendIfNotBlank(s, System.lineSeparator());
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null}.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @return the modified string with the prefix and suffix added if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String affixIfNotNull(String s, String prefix, String suffix) {
return affixIfNotNull(s, prefix, suffix, EMPTY, EMPTY);
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null}, using default values
* for the prefix and suffix if they are {@code null}.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the modified string with the prefix and suffix (or their defaults) added if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String affixIfNotNull(String s, String prefix, String suffix, String defaultPrefix, String defaultSuffix) {
if (s == null) return null;
return defaultIfNull(prefix, defaultPrefix) + s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null} or empty.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @return the modified string with the prefix and suffix added if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String affixIfNotEmpty(String s, String prefix, String suffix) {
return affixIfNotEmpty(s, prefix, suffix, EMPTY, EMPTY);
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null} or empty, using default values for
* the prefix and suffix if they are {@code null}.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the modified string with the prefix and suffix (or their defaults) added if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String affixIfNotEmpty(String s, String prefix, String suffix, String defaultPrefix, String defaultSuffix) {
if (isNullOrEmpty(s)) return s;
return defaultIfNull(prefix, defaultPrefix) + s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null} or blank.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @return the modified string with the prefix and suffix added if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String affixIfNotBlank(String s, String prefix, String suffix) {
return affixIfNotBlank(s, prefix, suffix, EMPTY, EMPTY);
}
/**
* Adds the specified prefix and suffix to the string if it is not {@code null} or blank, using default values
* for the prefix and suffix if they are {@code null}.
*
* @param s the string to modify
* @param prefix the prefix to add
* @param suffix the suffix to add
* @param defaultPrefix the default prefix to use if {@code prefix} is {@code null}
* @param defaultSuffix the default suffix to use if {@code suffix} is {@code null}
* @return the modified string with the prefix and suffix (or their defaults) added if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String affixIfNotBlank(String s, String prefix, String suffix, String defaultPrefix, String defaultSuffix) {
if (isNullOrBlank(s)) return s;
return defaultIfNull(prefix, defaultPrefix) + s + defaultIfNull(suffix, defaultSuffix);
}
/**
* Adds a space to both the beginning and end of the specified string if it is not {@code null}.
*
* @param s the string to modify
* @return the modified string with spaces added at both ends if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String affixSpacesIfNotNull(String s) {
return affixIfNotNull(s, String.valueOf(Separator.SPACE.getCharacter()), String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Adds a space to both the beginning and end of the specified string if it is not {@code null} or empty.
*
* @param s the string to modify
* @return the modified string with spaces added at both ends if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String affixSpacesIfNotEmpty(String s) {
return affixIfNotEmpty(s, String.valueOf(Separator.SPACE.getCharacter()), String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Adds a space to both the beginning and end of the specified string if it is not {@code null} or blank.
*
* @param s the string to modify
* @return the modified string with spaces added at both ends if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String affixSpacesIfNotBlank(String s) {
return affixIfNotBlank(s, String.valueOf(Separator.SPACE.getCharacter()), String.valueOf(Separator.SPACE.getCharacter()));
}
/**
* Adds a hyphen to both the beginning and end of the specified string if it is not {@code null}.
*
* @param s the string to modify
* @return the modified string with hyphens added at both ends if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String affixHyphensIfNotNull(String s) {
return affixIfNotNull(s, String.valueOf(Separator.HYPHEN.getCharacter()), String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Adds a hyphen to both the beginning and end of the specified string if it is not {@code null} or empty.
*
* @param s the string to modify
* @return the modified string with hyphens added at both ends if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String affixHyphensIfNotEmpty(String s) {
return affixIfNotEmpty(s, String.valueOf(Separator.HYPHEN.getCharacter()), String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Adds a hyphen to both the beginning and end of the specified string if it is not {@code null} or blank.
*
* @param s the string to modify
* @return the modified string with hyphens added at both ends if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String affixHyphensIfNotBlank(String s) {
return affixIfNotBlank(s, String.valueOf(Separator.HYPHEN.getCharacter()), String.valueOf(Separator.HYPHEN.getCharacter()));
}
/**
* Adds a line break to both the beginning and end of the specified string if it is not {@code null}.
*
* @param s the string to modify
* @return the modified string with line breaks added at both ends if {@code s} is not {@code null};
* otherwise, returns {@code null}
*/
public static String affixLineBreaksIfNotNull(String s) {
return affixIfNotNull(s, System.lineSeparator(), System.lineSeparator());
}
/**
* Adds a line break to both the beginning and end of the specified string if it is not {@code null} or empty.
*
* @param s the string to modify
* @return the modified string with line breaks added at both ends if {@code s} is not {@code null} or empty;
* otherwise, returns the original string
*/
public static String affixLineBreaksIfNotEmpty(String s) {
return affixIfNotEmpty(s, System.lineSeparator(), System.lineSeparator());
}
/**
* Adds a line break to both the beginning and end of the specified string if it is not {@code null} or blank.
*
* @param s the string to modify
* @return the modified string with line breaks added at both ends if {@code s} is not {@code null} or blank;
* otherwise, returns the original string
*/
public static String affixLineBreaksIfNotBlank(String s) {
return affixIfNotBlank(s, System.lineSeparator(), System.lineSeparator());
}
/**
* Wraps the given string in quotation marks if it is not {@code null} or blank.
* Uses “ and ” as the quotation marks to enclose the string.
*
* @param s the string to be quoted
* @return the quoted string if {@code s} is not {@code null} or blank; otherwise, returns the original string
*/
public static String quote(String s) {
return affixIfNotBlank(s, "“", "”");
}
/**
* Pads the given string on the left to reach a specified length. If the specified padding character
* is the {@code null} character, a space is used instead.
* This method ensures the resulting string reaches a specific minimum length by adding the specified character
* to the beginning of the string as many times as needed.
*
* @param s the string to be padded
* @param length the target length of the string after padding
* @param padChar the character to use for padding. If this character is the {@code null} character, a space will be used.
* @return the left-padded string, or {@code null} if the input string is {@code null}
*/
public static String padLeft(String s, int length, char padChar) {
if (s == null) return null;
if (CharHelper.isNull(padChar)) padChar = Separator.SPACE.getCharacter();
StringBuilder sb = new StringBuilder(s);
while (sb.length() < length) {
sb.insert(0, padChar);
}
return sb.toString();
}
/**
* Pads the given string on the right to reach a specified length. If the specified padding character
* is the {@code null} character, a space is used instead.
* This method ensures the resulting string reaches a specific minimum length by adding the specified character
* to the end of the string as many times as needed.
*
* @param s the string to be padded
* @param length the target length of the string after padding
* @param padChar the character to use for padding. If this character is the {@code null} character, a space will be used.
* @return the right-padded string, or {@code null} if the input string is {@code null}
*/
public static String padRight(String s, int length, char padChar) {
if (s == null) return null;
if (CharHelper.isNull(padChar)) padChar = Separator.SPACE.getCharacter();
StringBuilder sb = new StringBuilder(s);
while (sb.length() < length) {
sb.append(padChar);
}
return sb.toString();
}
/**
* Splits a string into an array of substrings based on the matches of the given regular expression.
*
* @param s the string to be split
* @param regex the regular expression to match the delimiter
* @return an array of substrings split from the input string, or an empty array if either {@code s}
* or {@code regex} is {@code null} or empty
*/
public static String[] split(String s, String regex) {
if (s == null || isNullOrEmpty(regex)) return new String[]{};
return s.split(regex);
}
/**
* Splits a string into an array of substrings using a single character as the delimiter.
*
* @param s the string to be split
* @param delimiter the character used as the delimiter
* @return an array of substrings split from the input string, or an empty array if {@code s} is {@code null}
*/
public static String[] split(String s, char delimiter) {
if (s == null) return new String[]{};
String[] temp = new String[(s.length() / 2) + 1];
int partCount = 0;
int i = 0;
int j = s.indexOf(delimiter);
while (j >= 0) {
temp[partCount++] = s.substring(i, j);
i = j + 1;
j = s.indexOf(delimiter, i);
}
temp[partCount++] = s.substring(i);
String[] result = new String[partCount];
System.arraycopy(temp, 0, result, 0, partCount);
return result;
}
/**
* Splits a string into an array of substrings using a specified string as the delimiter.
*
* @param s the string to be split
* @param delimiter the string used as the delimiter
* @return an array of substrings split from the input string, or an empty array if {@code s} is {@code null}
* or does not contain the delimiter
*/
public static String[] splitByDelimiter(String s, String delimiter) {
if (s == null) return new String[]{};
if (delimiter == null || s.length() < delimiter.length()) return new String[]{s};
String[] parts = new String[s.length() / 2];
int partCount = 0;
int index = s.indexOf(delimiter);
int startIndex = 0;
int endIndex;
while (index >= 0) {
endIndex = index;
if (startIndex < endIndex) {
parts[partCount] = s.substring(startIndex, endIndex);
partCount++;
}
startIndex = endIndex + delimiter.length();
index = s.indexOf(delimiter, index + 1);
}
if (startIndex < s.length() - 1) {
parts[partCount] = s.substring(startIndex);
partCount++;
}
String[] result = new String[partCount];
System.arraycopy(parts, 0, result, 0, partCount);
return result;
}
/**
* Splits a string into an array of substrings using a space character as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitBySpace(String s) {
return split(s, Separator.SPACE.getCharacter());
}
/**
* Splits a string into an array of substrings using a hyphen character as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitByHyphen(String s) {
return split(s, Separator.HYPHEN.getCharacter());
}
/**
* Splits a string into an array of substrings using the system's line separator as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitByLineBreak(String s) {
return splitByDelimiter(s, System.lineSeparator());
}
/**
* Splits a string into an array of substrings using the paragraph mark (¶) followed by optional spaces as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitByParagraphMark(String s) {
return split(s, "¶[ ]*");
}
/**
* Splits a string into an array of substrings using a comma followed by optional spaces as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitByComma(String s) {
return split(s, ",[ ]*");
}
/**
* Splits a string into an array of substrings using a tab character followed by optional spaces as the delimiter.
*
* @param s the string to be split
* @return an array of substrings split from the input string
*/
public static String[] splitByTab(String s) {
return split(s, "\t[ ]*");
}
/**
* Concatenates two strings, replacing any {@code null} values with empty strings before concatenation.
*
* @param a the first string to concatenate
* @param b the second string to concatenate
* @return the concatenated result of {@code a} and {@code b}, with {@code null} values replaced by empty strings
*/
public static String connect(String a, String b) {
a = defaultIfNull(a);
b = defaultIfNull(b);
return a + b;
}
/**
* Joins an array of strings using a specified character as the separator.
*
* @param c the character to use as a separator
* @param strings the array of strings to join
* @return a single string composed of all the elements in {@code strings}, separated by {@code c}
*/
public static String join(char c, String... strings) {
return join(String.valueOf(c), strings);
}
/**
* Joins a list of strings using a specified character as the separator.
*
* @param c the character to use as a separator
* @param strings the list of strings to join
* @return a single string composed of all the elements in {@code strings}, separated by {@code c},
* or {@code null} if {@code strings} is {@code null}
*/
public static String join(char c, List strings) {
if (strings == null) return null;
return join(String.valueOf(c), strings.toArray(new String[0]));
}
/**
* Joins an array of strings using a specified string as the separator.
*
* @param separator the string to use as a separator
* @param strings the array of strings to join
* @return a single string composed of all the elements in {@code strings}, separated by {@code separator}
*/
public static String join(String separator, String... strings) {
StringBuilder sb = new StringBuilder();
separator = defaultIfNull(separator);
for (String s : strings) {
if (isNotNullOrEmpty(s)) {
if (sb.length() > 0) sb.append(separator);
sb.append(s);
}
}
return sb.toString();
}
/**
* Joins a list of strings using a specified string as the separator.
*
* @param separator the string to use as a separator
* @param strings the list of strings to join
* @return a single string composed of all the elements in {@code strings}, separated by {@code separator},
* or {@code null} if {@code strings} is {@code null}
*/
public static String join(String separator, List strings) {
if (strings == null) return null;
return join(separator, strings.toArray(new String[0]));
}
/**
* Joins an array of strings without any separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} concatenated together without any separator
*/
public static String joinWithoutSeparator(String... strings) {
return join(EMPTY, strings);
}
/**
* Joins a list of strings without any separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} concatenated together without any separator,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithoutSeparator(List strings) {
if (strings == null) return null;
return joinWithoutSeparator(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using a space as the separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by a space
*/
public static String joinWithSpace(String... strings) {
return join(String.valueOf(Separator.SPACE.getCharacter()), strings);
}
/**
* Joins a list of strings using a space as the separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by a space,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithSpace(List strings) {
if (strings == null) return null;
return joinWithSpace(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using a hyphen as the separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by a hyphen
*/
public static String joinWithHyphen(String... strings) {
return join(String.valueOf(Separator.HYPHEN.getCharacter()), strings);
}
/**
* Joins a list of strings using a hyphen as the separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by a hyphen,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithHyphen(List strings) {
if (strings == null) return null;
return joinWithHyphen(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using the system's line separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by the system's line separator
*/
public static String joinWithLineBreak(String... strings) {
return join(System.lineSeparator(), strings);
}
/**
* Joins a list of strings using the system's line separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by the system's line separator,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithLineBreak(List strings) {
if (strings == null) return null;
return joinWithLineBreak(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using a forward slash as the separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by a forward slash
*/
public static String joinWithSlash(String... strings) {
return join(String.valueOf('/'), strings);
}
/**
* Joins a list of strings using a forward slash as the separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by a forward slash,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithSlash(List strings) {
if (strings == null) return null;
return joinWithSlash(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using a backslash as the separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by a backslash
*/
public static String joinWithBackslash(String... strings) {
return join(String.valueOf('\\'), strings);
}
/**
* Joins a list of strings using a backslash as the separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by a backslash,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithBackslash(List strings) {
if (strings == null) return null;
return joinWithBackslash(strings.toArray(new String[0]));
}
/**
* Joins an array of strings using the platform-specific file separator.
*
* @param strings the array of strings to join
* @return a single string composed of all elements in {@code strings} separated by the platform-specific file separator
*/
public static String joinWithFileSeparator(String... strings) {
return join(File.separator, strings);
}
/**
* Joins a list of strings using the platform-specific file separator.
*
* @param strings the list of strings to join
* @return a single string composed of all elements in {@code strings} separated by the platform-specific file separator,
* or {@code null} if {@code strings} is {@code null}
*/
public static String joinWithFileSeparator(List strings) {
if (strings == null) return null;
return joinWithFileSeparator(strings.toArray(new String[0]));
}
/**
* Welds two strings together, making adjustments based on the ending character of the first string and the starting character of the second string.
* If the ending character of the first string and the starting character of the second string are the same, it removes the duplicate character.
* If one is a vowel and the other isn't, or if either character is not a letter, it simply concatenates the two strings.
* Otherwise, it removes the appropriate character to ensure smooth concatenation.
*
* @param a the first string to weld
* @param b the second string to weld
* @return the welded string, or an empty string if either input is {@code null} or empty
*/
public static String weld(String a, String b) {
if (isNullOrEmpty(a) || isNullOrEmpty(b)) return EMPTY;
char ending = getLastChar(a);
char start = getFirstChar(b);
boolean vowel;
if (ending == start) return removeLastChar(a) + b;
if (!Character.isLetter(ending) || !Character.isLetter(start)) return a + b;
if ((vowel = CharHelper.isVowel(ending)) ^ CharHelper.isVowel(start)) return a + b;
return vowel ? (a + removeFirstChar(b)) : (removeLastChar(a) + b);
}
/**
* Repeats the given string a specified number of times.
*
* @param s the string to repeat
* @param count the number of times to repeat the string
* @return the concatenated string after repeating, or {@code null} if the input string is {@code null} or the count is negative
*/
public static String repeat(String s, int count) {
if (s == null || count < 0) return null;
return s.repeat(count);
}
/**
* Trims whitespace from the beginning and end of the given string.
*
* @param s the string to trim
* @return the trimmed string, or {@code null} if the input string is {@code null}
*/
public static String trim(String s) {
return s == null ? null : s.trim();
}
/**
* Trims the given string and returns {@code null} if the result is an empty string.
*
* @param s the string to trim
* @return the trimmed string, or {@code null} if the result is empty or the input is {@code null}
*/
public static String trimToNull(String s) {
s = trim(s);
return isNullOrEmpty(s) ? null : s;
}
/**
* Trims the given string and returns an empty string if the input is {@code null}.
*
* @param s the string to trim
* @return the trimmed string, or an empty string if the input is {@code null}
*/
public static String trimToEmpty(String s) {
return s == null ? EMPTY : s.trim();
}
/**
* Trims the given string and returns a default value if the result is an empty string.
* Overloaded to use a predefined default value.
*
* @param s the string to trim
* @return the trimmed string, or {@value #DEFAULT_VALUE} if the result is empty
*/
public static String trimOrDefault(String s) {
return trimOrDefault(s, DEFAULT_VALUE);
}
/**
* Trims the given string and returns a specified default value if the result is an empty string.
*
* @param s the string to trim
* @param defaultValue the default value to return if the trimmed string is empty
* @return the trimmed string, or the specified default value if the result is empty
*/
public static String trimOrDefault(String s, String defaultValue) {
return defaultIfEmpty(trimToEmpty(s), defaultValue);
}
/**
* Strips whitespace from both ends of the given string.
*
* @param s the string to strip
* @return the stripped string, or {@code null} if the input string is {@code null}
*/
public static String strip(String s) {
return s == null ? null : s.strip();
}
/**
* Strips whitespace from both ends of the given string and returns {@code null} if the result is an empty string.
*
* @param s the string to strip
* @return the stripped string, or {@code null} if the result is empty or the input is {@code null}
*/
public static String stripToNull(String s) {
s = strip(s);
return isNullOrEmpty(s) ? null : s;
}
/**
* Strips whitespace from both ends of the given string and returns an empty string if the input is {@code null}.
*
* @param s the string to strip
* @return the stripped string, or an empty string if the input is {@code null}
*/
public static String stripToEmpty(String s) {
return s == null ? EMPTY : s.strip();
}
/**
* Strips whitespace from both ends of the given string and returns a default value if the result is an empty string.
* Overloaded to use a predefined default value.
*
* @param s the string to strip
* @return the stripped string, or {@value #DEFAULT_VALUE} if the result is empty
*/
public static String stripOrDefault(String s) {
return stripOrDefault(s, DEFAULT_VALUE);
}
/**
* Strips whitespace from both ends of the given string and returns a specified default value if the result is an empty string.
*
* @param s the string to strip
* @param defaultValue the default value to return if the stripped string is empty
* @return the stripped string, or the specified default value if the result is empty
*/
public static String stripOrDefault(String s, String defaultValue) {
return defaultIfEmpty(stripToEmpty(s), defaultValue);
}
/**
* Removes leading whitespace from the given string.
*
* @param s the string from which to remove leading whitespace
* @return the string with leading whitespace removed
*/
public static String stripStart(String s) {
if (isNullOrEmpty(s)) return s;
int index = 0;
while (Character.isWhitespace(s.charAt(index))) {
index++;
}
return s.substring(index);
}
/**
* Removes trailing whitespace from the given string.
*
* @param s the string from which to remove trailing whitespace
* @return the string with trailing whitespace removed
*/
public static String stripEnd(String s) {
if (isNullOrEmpty(s)) return s;
int index = s.length() - 1;
while (Character.isWhitespace(s.charAt(index))) {
index--;
}
return s.substring(0, index + 1);
}
/**
* Strips indent (leading and trailing whitespace) from the given string.
*
* @param s the string from which to strip indent
* @return the string with indent stripped
*/
public static String stripIndent(String s) {
s = stripStart(s);
return stripEnd(s);
}
/**
* Normalizes a string to its ASCII form by removing diacritics (accents) and then filters out non-ASCII characters.
*
* @param s the string to normalize
* @return the normalized ASCII string, or the original string if it is {@code null} or empty
*/
public static String normalize(String s) {
if (isNullOrEmpty(s)) return s;
String normalized = Normalizer.normalize(s, Normalizer.Form.NFD);
return RegexFilter.EXCEPT_ASCII_PATTERN.matcher(normalized).replaceAll(EMPTY);
}
/**
* Normalizes a string to its ASCII form and removes all characters that are not alphabetic letters.
*
* @param s the string to normalize and clean
* @return the normalized string containing only ASCII alphabetic characters,
* or the original string if it is {@code null} or empty
*/
public static String normalizeAlpha(String s) {
s = normalize(s);
return StringFilter.keepAsciiAlpha(s);
}
/**
* Normalizes a string to its ASCII form and removes all characters that are not alphanumeric.
*
* @param s the string to normalize and clean
* @return the normalized string containing only ASCII alphanumeric characters,
* or the original string if it is {@code null} or empty
*/
public static String normalizeAlphanumeric(String s) {
s = normalize(s);
return StringFilter.keepAsciiAlphanumeric(s);
}
/**
* Normalizes a string to its ASCII form and removes all characters except alphabetic letters and whitespaces.
*
* @param s the string to normalize and clean
* @return the normalized string containing only ASCII alphabetic characters and whitespaces,
* or the original string if it is {@code null} or empty
*/
public static String normalizeAlphaWhitespace(String s) {
s = normalize(s);
return StringFilter.keepAsciiAlphaOrWhitespaces(s);
}
/**
* Normalizes a string to its ASCII form and removes all characters except alphanumeric characters and whitespaces.
*
* @param s the string to normalize and clean
* @return the normalized string containing only ASCII alphanumeric characters and whitespaces,
* or the original string if it is {@code null} or empty
*/
public static String normalizeAlphanumericWhitespace(String s) {
s = normalize(s);
return StringFilter.keepAlphanumericOrWhitespaces(s);
}
/**
* Strips accents from a string, leaving behind the base characters.
*
* @param s the string from which to strip accents
* @return the string with accents removed, or the original string if it is {@code null} or empty
*/
public static String stripAccents(String s) {
if (isNullOrEmpty(s)) return s;
String normalized = Normalizer.normalize(s, Normalizer.Form.NFD);
return RegexFilter.DIACRITIC_PATTERN.matcher(normalized).replaceAll(EMPTY);
}
/**
* Converts a given string to uppercase.
*
* @param s the string to convert
* @return the uppercase version of the string, or the original string if it is {@code null} or empty
*/
public static String toUppercase(String s) {
if (isNullOrEmpty(s)) return s;
return s.toUpperCase();
}
/**
* Converts a given string to lowercase.
*
* @param s the string to convert
* @return the lowercase version of the string, or the original string if it is {@code null} or empty
*/
public static String toLowercase(String s) {
if (isNullOrEmpty(s)) return s;
return s.toLowerCase();
}
/**
* Converts the first character of the specified string to uppercase. All other characters
* in the string are converted to lowercase.
*
* @param s the input string to be modified
* @return a string with the first character converted to uppercase, if applicable
*/
public static String capitalizeFirst(String s) {
return capitalize(s, 1L);
}
/**
* Converts the first character of each word in the specified string to uppercase. All other characters
* in each word are converted to lowercase.
*
* @param s the input string to be modified
* @return a string with the first character of each word capitalized and the rest in lowercase
*/
public static String capitalize(String s) {
return capitalize(s, Long.MAX_VALUE);
}
/**
* Converts the first N characters of the specified string to uppercase, where N is determined by
* the {@code remainingMatches} parameter. Once the limit is reached, the rest of the characters are
* converted to lowercase.
*
* @param s the input string to be modified
* @param remainingMatches the number of characters to be converted to uppercase
* @return a modified string based on the {@code remainingMatches} criteria
*/
private static String capitalize(String s, long remainingMatches) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
boolean upperPending = true;
long replacementCount = 0L;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isWhitespace(c)) upperPending = true;
else if (upperPending && replacementCount < remainingMatches) {
chars[i] = Character.toUpperCase(c);
replacementCount++;
upperPending = false;
} else chars[i] = Character.toLowerCase(c);
}
return new String(chars);
}
/**
* Converts the first character of the specified string to uppercase. This method
* does not alter the case of the other characters in the string.
*
* @param s the input string to be modified
* @return a string with its first character converted to uppercase, if applicable
*/
public static String capitalizeStart(String s) {
return capitalizeStarts(s, 1L);
}
/**
* Converts the first character of each word in the specified string to uppercase.
* This method does not alter the case of the other characters within each word.
*
* @param s the input string to be modified
* @return a string with the first character of each word converted to uppercase
*/
public static String capitalizeStarts(String s) {
return capitalizeStarts(s, Long.MAX_VALUE);
}
/**
* Converts the first character of each word in the specified string to uppercase,
* limited by the specified number of matches. This method does not alter the case
* of the other characters within each word after the specified number of matches.
*
* @param s the input string to be modified
* @param remainingMatches the maximum number of words to apply the capitalization
* @return a string with the first character of each word converted to uppercase,
* up to the specified number of matches
*/
private static String capitalizeStarts(String s, long remainingMatches) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
boolean upperPending = true;
long replacementCount = 0L;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isWhitespace(c)) upperPending = true;
else if (upperPending) {
if (replacementCount >= remainingMatches) break;
chars[i] = Character.toUpperCase(c);
replacementCount++;
upperPending = false;
}
}
return new String(chars);
}
/**
* Converts the first character of the specified string to lowercase. All other characters
* in the string are converted to uppercase.
*
* @param s the input string to be modified
* @return a string with the first character converted to lowercase, if applicable
*/
public static String toUppercaseExceptStart(String s) {
return toUppercaseExceptStarts(s, 1L);
}
/**
* Converts the first character of each word in the specified string to lowercase. All other characters
* in each word are converted to uppercase.
*
* @param s the input string to be modified
* @return a string with the first character of each word in lowercase and the rest in uppercase
*/
public static String toUppercaseExceptStarts(String s) {
return toUppercaseExceptStarts(s, Long.MAX_VALUE);
}
/**
* Converts the first N characters of the specified string to lowercase, where N is determined by
* the {@code remainingMatches} parameter. Once the limit is reached, the rest of the characters are
* converted to uppercase.
*
* @param s the input string to be modified
* @param remainingMatches the number of characters to be converted to lowercase
* @return a modified string based on the {@code remainingMatches} criteria
*/
private static String toUppercaseExceptStarts(String s, long remainingMatches) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
boolean lowerPending = true;
long replacementCount = 0L;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isWhitespace(c)) lowerPending = true;
else if (lowerPending && replacementCount < remainingMatches) {
chars[i] = Character.toLowerCase(c);
replacementCount++;
lowerPending = false;
} else chars[i] = Character.toUpperCase(c);
}
return new String(chars);
}
/**
* Converts the first character of the specified string to lowercase. This method
* does not alter the case of the other characters in the string.
*
* @param s the input string to be modified
* @return a string with its first character converted to lowercase, if applicable
*/
public static String uncapitalizeStart(String s) {
return uncapitalizeStarts(s, 1L);
}
/**
* Converts the first character of each word in the specified string to lowercase.
* This method does not alter the case of the other characters within each word.
*
* @param s the input string to be modified
* @return a string with the first character of each word converted to lowercase
*/
public static String uncapitalizeStarts(String s) {
return uncapitalizeStarts(s, Long.MAX_VALUE);
}
/**
* Converts the first character of each word in the specified string to lowercase,
* limited by the specified number of matches. This method does not alter the case
* of the other characters within each word after the specified number of matches.
*
* @param s the input string to be modified
* @param remainingMatches the maximum number of words to apply the lowercase conversion
* @return a string with the first character of each word converted to lowercase,
* up to the specified number of matches
*/
private static String uncapitalizeStarts(String s, long remainingMatches) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
boolean lowerPending = true;
long replacementCount = 0L;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isWhitespace(c)) lowerPending = true;
else if (lowerPending) {
if (replacementCount >= remainingMatches) break;
chars[i] = Character.toLowerCase(c);
replacementCount++;
lowerPending = false;
}
}
return new String(chars);
}
/**
* Swaps uppercase characters to lowercase and vice versa in a given string.
*
* @param s the string whose case is to be swapped
* @return a new string with all uppercase characters converted to lowercase
* and all lowercase characters converted to uppercase
*/
public static String swapCase(String s) {
if (isNullOrEmpty(s)) return s;
StringBuilder sb = new StringBuilder(s.length());
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c)) sb.append(Character.toLowerCase(c));
else sb.append(Character.toUpperCase(c));
}
return sb.toString();
}
/**
* Transforms the case of the input string randomly. Each character in the string
* that is a letter will be randomly transformed to either uppercase or lowercase.
* Non-letter characters are not affected by this transformation.
*
* @param s the input string to be converted
* @return a new string where the case of each letter has been randomly transformed,
* or the original string if it is {@code null} or empty
*/
public static String randomCase(String s) {
return randomCase(s, null);
}
/**
* Transforms the case of the input string randomly. Each character in the string
* that is a letter will be randomly transformed to either uppercase or lowercase.
* Non-letter characters are not affected by this transformation.
*
* @param s the input string to be converted
* @param seed the seed used for the randomization, or {@code null} for a random seed
* @return a new string where the case of each letter has been randomly transformed,
* or the original string if it is {@code null} or empty
*/
public static String randomCase(String s, Long seed) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
Random r = new Random();
if (seed != null) r.setSeed(seed);
for (int i = 0; i < chars.length; i++) {
if (Character.isLetter(chars[i])) {
if (r.nextBoolean()) chars[i] = Character.toUpperCase(chars[i]);
else chars[i] = Character.toLowerCase(chars[i]);
}
}
return new String(chars);
}
/**
* Converts a given string into camelCase format.
*
* This method transforms the input string to camelCase, where the first letter of the
* first word is lowercase, and the first letter of each subsequent word is capitalized
* while the rest are in lowercase. Non-alphanumeric characters such as whitespace,
* underscores (_), and hyphens (-) are removed, and they signify the start of a new word.
*
* @param s the input string to be converted
* @return the converted string in camelCase format; if the input is {@code null} or empty, returns the original input
*/
public static String toCamelCase(String s) {
if (isNullOrEmpty(s)) return s;
StringBuilder sb = new StringBuilder();
boolean upperPending = false;
for (char c : s.toCharArray()) {
if (Character.isWhitespace(c) || c == '_' || c == '-') upperPending = true;
else if (Character.isLetterOrDigit(c)) {
if (upperPending) {
sb.append(Character.toUpperCase(c));
upperPending = false;
} else sb.append(Character.toLowerCase(c));
}
}
return sb.toString();
}
/**
* Converts a given string into PascalCase format.
*
* This method transforms the input string to PascalCase, where the first letter of
* each word is capitalized and the rest are in lowercase. Non-alphanumeric characters
* such as whitespace, underscores (_), and hyphens (-) are removed, and they signify
* the start of a new word.
*
* @param s the input string to be converted
* @return the converted string in PascalCase format; if the input is {@code null} or empty, returns the original input
*/
public static String toPascalCase(String s) {
if (isNullOrEmpty(s)) return s;
StringBuilder sb = new StringBuilder();
boolean upperPending = true;
for (char c : s.toCharArray()) {
if (Character.isWhitespace(c) || c == '_' || c == '-') upperPending = true;
else if (Character.isLetterOrDigit(c)) {
if (upperPending) {
sb.append(Character.toUpperCase(c));
upperPending = false;
} else sb.append(Character.toLowerCase(c));
}
}
return sb.toString();
}
/**
* Transforms the case of a string to a specified format. The function supports various case styles
* typically used in programming such as camelCase, PascalCase, snake_case, and others. This method
* is useful for standardizing string formats for code identifiers or data processing.
*
* Supported Naming Conventions:
*
* - PASCAL_CASE: "PascalCase"
* - CAMEL_CASE: "camelCase"
* - SNAKE_CASE: "snake_case"
* - KEBAB_CASE: "kebab-case"
* - FLAT_CASE: "flatcase"
* - UPPER_FLAT_CASE: "UPPERFLATCASE"
* - PASCAL_SNAKE_CASE: "Pascal_Snake_Case"
* - CAMEL_SNAKE_CASE: "camel_Snake_Case"
* - SCREAMING_SNAKE_CASE: "SCREAMING_SNAKE_CASE"
* - TRAIN_CASE: "Train-Case"
* - COBOL_CASE: "COBOL-CASE"
*
*
* Non-alphanumeric characters in the input are treated as word boundaries and are not included in the
* output unless they are part of the target case style's formatting.
*
* @param s the string to convert
* @param caseStyle the case style to apply
* @return the converted string, or the original string if it is {@code null} or empty
*/
public static String convertCase(String s, CaseStyle caseStyle) {
if (isNullOrEmpty(s) || caseStyle == null) return s;
s += Separator.SPACE.getCharacter();
char[] chars = s.toCharArray();
char prevChar = chars[0];
StringBuilder sb = new StringBuilder();
for (int n = 0; n < chars.length - 1; n++) {
char c = chars[n];
char nextChar = chars[n + 1];
if (!CharHelper.isDelimiter(prevChar) && CharHelper.isDelimiter(c) && Character.isLetterOrDigit(nextChar)) {
switch (caseStyle) {
case SNAKE_CASE, PASCAL_SNAKE_CASE, CAMEL_SNAKE_CASE, SCREAMING_SNAKE_CASE -> sb.append('_');
case KEBAB_CASE, TRAIN_CASE, COBOL_CASE -> sb.append('-');
}
} else {
if (!Character.isLetterOrDigit(c)) continue;
switch (caseStyle) {
case PASCAL_CASE, PASCAL_SNAKE_CASE, TRAIN_CASE -> {
if (sb.length() == 0 || CharHelper.isDelimiter(prevChar)) sb.append(Character.toUpperCase(c));
else sb.append(Character.toLowerCase(c));
}
case CAMEL_CASE, CAMEL_SNAKE_CASE -> {
if (sb.length() > 0 && CharHelper.isDelimiter(prevChar)) sb.append(Character.toUpperCase(c));
else sb.append(Character.toLowerCase(c));
}
case SNAKE_CASE, KEBAB_CASE, FLAT_CASE -> sb.append(Character.toLowerCase(c));
case UPPER_FLAT_CASE, SCREAMING_SNAKE_CASE, COBOL_CASE -> sb.append(Character.toUpperCase(c));
}
}
prevChar = c;
}
return sb.toString();
}
/**
* Reverses the characters of the given string.
*
* @param s the string to be reversed
* @return the reversed string, or the original string if it is {@code null} or empty
*/
public static String reverse(String s) {
if (isNullOrEmpty(s)) return s;
return new StringBuilder(s).reverse().toString();
}
/**
* Masks all non-space characters in a string with asterisks.
*
* @param s the string to be masked
* @return the masked string where all characters are replaced by '*', or the original string if it is {@code null} or empty
*/
public static String mask(String s) {
return mask(s, '*');
}
/**
* Masks all non-space characters in a string with a specified replacement character.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String mask(String s, char replacement) {
if (isNullOrEmpty(s)) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
return RegexFilter.EXCEPT_SPACE_PATTERN.matcher(s).replaceAll(String.valueOf(replacement));
}
/**
* Masks a specific range of characters in a string.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @param start the starting index (inclusive) of the range to mask
* @param end the ending index (inclusive) of the range to mask
* @return a masked string with the specified range masked; or the original string
* if it is {@code null} or empty, or if the range is invalid
*/
public static String mask(String s, char replacement, int start, int end) {
if (isNullOrEmpty(s)) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (start > end || start < 0 || end >= s.length()) return s;
return s.substring(0, start) + String.valueOf(replacement).repeat(end - start + 1) + s.substring(end + 1);
}
/**
* Masks the beginning of a string with asterisks, leaving the last four characters visible.
*
* @param s the string to be masked
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskStart(String s) {
return maskStart(s, '*');
}
/**
* Masks the beginning of a string with a specified replacement character, leaving the last four characters visible.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskStart(String s, char replacement) {
if (isNullOrEmpty(s)) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() > 4) return s.replaceAll("\\S(?=.{4})", String.valueOf(replacement));
return String.valueOf(replacement).repeat(s.length());
}
/**
* Masks the beginning of a string, leaving a specified number of characters at the end unmasked.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @param unmaskedChars the number of characters at the end of the string to leave unmasked
* @return a masked string with the specified end characters unmasked;
* or the original string if it is {@code null} or empty, or if {@code unmaskedChars} is equal or less than 0;
* but if the string length is less than or equal to {@code unmaskedChars}, the entire string is masked
*/
public static String maskStart(String s, char replacement, int unmaskedChars) {
if (isNullOrEmpty(s) || unmaskedChars <= 0) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() <= unmaskedChars) return String.valueOf(replacement).repeat(s.length());
return String.valueOf(replacement).repeat(s.length() - unmaskedChars) + s.substring(s.length() - unmaskedChars);
}
/**
* Masks the middle characters of a given string with asterisks, depending on the string's length.
* Utilizes different masking rules based on the string length:
*
* - If length ≤ 4, replaces all characters.
* - If length between 5 and 8, masks all except the first and last characters.
* - If length between 9 and 12, masks all except the first two and last two characters.
* - If length > 12, masks all except the first three and last three characters.
*
*
* @param s the string to be masked
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskMiddle(String s) {
return maskMiddle(s, '*');
}
/**
* Masks the middle characters of a given string using a specified replacement character, depending on the string's length.
* Utilizes different masking rules based on the string length:
*
* - If length ≤ 4, replaces all characters.
* - If length between 5 and 8, masks all except the first and last characters.
* - If length between 9 and 12, masks all except the first two and last two characters.
* - If length > 12, masks all except the first three and last three characters.
*
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskMiddle(String s, char replacement) {
if (isNullOrEmpty(s)) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() <= 4) return String.valueOf(replacement).repeat(s.length());
if (s.length() <= 8) return s.replaceAll("(?<=.)\\S(?=.)", String.valueOf(replacement));
if (s.length() <= 12) return s.replaceAll("(?<=.{2})\\S(?=.{2})", String.valueOf(replacement));
return s.replaceAll("(?<=.{3})\\S(?=.{3})", String.valueOf(replacement));
}
/**
* Masks a specific number of characters in the middle of a string, leaving the rest unmasked.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @param maskedChars the number of characters in the middle of the string to mask
* @return a masked string with the middle characters masked;
* or the original string if it is {@code null} or empty, or if {@code maskedChars} is equal or less than 0;
* but if the string length is less than or equal to {@code maskedChars}, the entire string is masked
*/
public static String maskMiddle(String s, char replacement, int maskedChars) {
if (isNullOrEmpty(s) || maskedChars <= 0) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() <= maskedChars) return String.valueOf(replacement).repeat(s.length());
int start = (s.length() - maskedChars) / 2;
int end = start + maskedChars;
return s.substring(0, start) + String.valueOf(replacement).repeat(maskedChars) + s.substring(end);
}
/**
* Masks the end of a string with asterisks, leaving the first four characters visible.
*
* @param s the string to be masked
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskEnd(String s) {
return maskEnd(s, '*');
}
/**
* Masks the end of a string with a specified replacement character, leaving the first four characters visible.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @return the masked string, or the original string if it is {@code null} or empty
*/
public static String maskEnd(String s, char replacement) {
if (isNullOrEmpty(s)) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() > 4) return s.replaceAll("(?<=.{4})\\S", String.valueOf(replacement));
return String.valueOf(replacement).repeat(s.length());
}
/**
* Masks the end of a string, leaving a specified number of characters at the beginning unmasked.
*
* @param s the string to be masked
* @param replacement the character used for masking, which, by default, is '*'
* @param unmaskedChars the number of characters at the beginning of the string to leave unmasked
* @return a masked string with the specified beginning characters unmasked;
* or the original string if it is {@code null} or empty, or if {@code unmaskedChars} is equal or less than 0;
* but if the string length is less than or equal to {@code unmaskedChars}, the entire string is masked
*/
public static String maskEnd(String s, char replacement, int unmaskedChars) {
if (isNullOrEmpty(s) || unmaskedChars <= 0) return s;
replacement = CharHelper.defaultIfNull(replacement, '*');
if (s.length() <= unmaskedChars) return String.valueOf(replacement).repeat(s.length());
return s.substring(0, unmaskedChars) + String.valueOf(replacement).repeat(s.length() - unmaskedChars);
}
/**
* Shuffles the characters of a string.
* Uses the Fisher-Yates algorithm for efficient, in-place shuffling.
*
* @param s the string to shuffle
* @return the shuffled string, or the original string if it is {@code null} or empty
*/
public static String shuffle(String s) {
return shuffle(s, null);
}
/**
* Shuffles the characters of a string.
* Uses the Fisher-Yates algorithm for efficient, in-place shuffling.
*
* @param s the string to shuffle
* @param seed the seed used for the randomization, or {@code null} for a random seed
* @return the shuffled string, or the original string if it is {@code null} or empty
*/
public static String shuffle(String s, Long seed) {
if (isNullOrEmpty(s)) return s;
char[] chars = s.toCharArray();
Random r = new Random();
if (seed != null) r.setSeed(seed);
for (int i = chars.length - 1; i > 0; i--) {
int index = r.nextInt(i + 1);
char temp = chars[index];
chars[index] = chars[i];
chars[i] = temp;
}
return new String(chars);
}
/**
* Extracts a substring from a string, with support for negative indices. Negative start or end indices are treated
* as offsets from the end of the string.
*
* @param s the original string
* @param startIndex the starting index of the substring, inclusive. If negative, it is treated as an offset
* from the end of the string.
* @param endIndex the ending index of the substring, exclusive. If negative, it is treated as an offset
* from the end of the string.
* @return the extracted substring or the original string if it is {@code null} or empty
*/
public static String substring(String s, int startIndex, int endIndex) {
if (isNullOrEmpty(s)) return s;
if (startIndex < 0) startIndex = s.length() + startIndex;
startIndex = IntegerHelper.defaultByRange(startIndex, 0, s.length());
if (endIndex < 0) endIndex = s.length() + endIndex;
endIndex = IntegerHelper.defaultByRange(endIndex, startIndex, s.length());
return s.substring(startIndex, endIndex);
}
/**
* Extracts the portion of a string before the first occurrence of a specified separator.
*
* @param s the original string
* @param separator the string to search for
* @return the substring before the first occurrence of the separator, or the original string if the separator
* is not found or {@code null}
*/
public static String substringBefore(String s, String separator) {
if (isNullOrEmpty(s) || separator == null) return s;
if (separator.isEmpty()) return EMPTY;
final int index = s.indexOf(separator);
if (index == INDEX_NOT_FOUND) return s;
return s.substring(0, index);
}
/**
* Extracts the substring between two substrings, using the first occurrence of each.
*
* @param s the original string
* @param open the string defining the start of the target substring
* @param close the string defining the end of the target substring
* @return the substring between the specified start and end strings, or {@code null} if any input is {@code null}
* or the delimiters are not found
*/
public static String substringBetween(String s, String open, String close) {
if (isNullOrEmpty(s) || isNullOrEmpty(open) || isNullOrEmpty(close)) return null;
int start = s.indexOf(open);
if (start != INDEX_NOT_FOUND) {
final int end = s.indexOf(close, start + open.length());
if (end != INDEX_NOT_FOUND) return s.substring(start + open.length(), end);
}
return null;
}
/**
* Extracts the portion of a string after the first occurrence of a specified separator.
*
* @param s the original string
* @param separator the string to search for
* @return the substring after the first occurrence of the separator, or an empty string if the separator is not found
*/
public static String substringAfter(String s, String separator) {
if (isNullOrEmpty(s)) return s;
if (separator == null) return EMPTY;
final int index = s.indexOf(separator);
if (index == INDEX_NOT_FOUND) return EMPTY;
return s.substring(index + separator.length());
}
/**
* Replaces every occurrence of a character in a string with another character.
* It utilizes {@code replace(String s, String occurrence, String replacement)}
* by converting characters to strings.
*
* @param s the original string
* @param occurrence the character to be replaced
* @param replacement the character to replace with
* @return the modified string with replacements, or {@code s} if it is {@code null} or empty
*/
public static String replace(String s, char occurrence, char replacement) {
if (isNullOrEmpty(s)) return s;
return s.replace(occurrence, replacement);
}
/**
* Replaces all occurrences of a substring within a string with another substring.
*
* @param s the original string
* @param occurrence the substring to find and replace
* @param replacement the substring to replace with
* @return the modified string with replacements, or {@code s} if it is {@code null} or empty
*/
public static String replace(String s, String occurrence, String replacement) {
if (isNullOrEmpty(s) || isNullOrEmpty(occurrence) || replacement == null) return s;
return s.replace(occurrence, replacement);
}
/**
* Replaces all occurrences of a substring within a string with another substring.
* This is a legacy method that was used before the optimizations in Java 11.
*
* @param s the original string
* @param occurrence the substring to find and replace
* @param replacement the substring to replace with
* @return the modified string with replacements, or {@code s} if it is {@code null} or empty
*/
public static String replaceWith(String s, String occurrence, String replacement) {
if (isNullOrEmpty(s) || isNullOrEmpty(occurrence) || replacement == null) return s;
int i = 0;
if ((i = s.indexOf(occurrence, i)) >= 0) {
char[] strChars = s.toCharArray();
char[] replacementChars = replacement.toCharArray();
int occurrenceLength = occurrence.length();
StringBuilder sb = new StringBuilder(strChars.length);
sb.append(strChars, 0, i).append(replacementChars);
i += occurrenceLength;
int j = i;
while ((i = s.indexOf(occurrence, i)) > 0) {
sb.append(strChars, j, i - j).append(replacementChars);
i += occurrenceLength;
j = i;
}
sb.append(strChars, j, strChars.length - j);
s = sb.toString();
sb.setLength(0);
}
return s;
}
/**
* Replaces a substring between specified indices with a replacement string.
*
* @param s the original string
* @param startIndex the beginning index, inclusive
* @param endIndex the ending index, exclusive
* @param replacement the string to replace the specified substring
* @return the modified string
*/
public static String replaceByIndex(String s, int startIndex, int endIndex, String replacement) {
if (isNullOrEmpty(s)) return s;
if (startIndex < 0) startIndex = s.length() + startIndex;
if (!IntegerHelper.isBetween(startIndex, 0, s.length() - 1)) return s;
if (endIndex < 0) endIndex = s.length() + endIndex;
if (!IntegerHelper.isBetween(endIndex, 0, s.length() - 1)) return s;
if (Math.abs(endIndex) < Math.abs(startIndex)) return s;
return new StringBuilder(s).replace(startIndex, endIndex, replacement).toString();
}
/**
* Replaces the first character of the given string with a replacement string.
*
* @param s the original string
* @param replacement the replacement string
* @return the string with the first character replaced
*/
public static String replaceFirstChar(String s, String replacement) {
if (isNotNullOrEmpty(s) && replacement != null) s = replacement + s.substring(1);
return s;
}
/**
* Replaces the last character of the given string with a replacement string.
*
* @param s the original string
* @param replacement the replacement string
* @return the string with the last character replaced
*/
public static String replaceLastChar(String s, String replacement) {
if (isNotNullOrEmpty(s) && replacement != null) s = s.substring(0, s.length() - 1) + replacement;
return s;
}
/**
* Replaces the first occurrence of a substring within the given string with a replacement string.
*
* @param s the original string
* @param occurrence the substring to be replaced
* @param replacement the replacement string
* @return the string with the first occurrence of the substring replaced
*/
public static String replaceOnce(String s, String occurrence, String replacement) {
int index = indexOf(s, occurrence);
if (index == -1) return s;
return s.substring(0, index).concat(replacement).concat(s.substring(index + occurrence.length()));
}
/**
* Replaces the final occurrence of a substring within the given string with a replacement string.
*
* @param s the original string
* @param occurrence the substring to be replaced
* @param replacement the replacement string
* @return the string with the final occurrence of the substring replaced
*/
public static String replaceFinal(String s, String occurrence, String replacement) {
if (isNullOrEmpty(s)) return s;
int lastIndex = s.lastIndexOf(occurrence);
if (lastIndex < 0) return s;
String tail = s.substring(lastIndex).replaceFirst(occurrence, replacement);
return s.substring(0, lastIndex) + tail;
}
/**
* Replaces the first occurrence of a regex pattern in the given string with a replacement string.
*
* @param s the original string
* @param regex the regex pattern to match
* @param replacement the replacement string
* @return the string with the first regex match replaced
*/
public static String replaceFirst(String s, String regex, String replacement) {
if (isNotNullOrEmpty(s) && replacement != null) return s.replaceFirst(regex, replacement);
return s;
}
/**
* Replaces the last occurrence of a regex pattern in the given string with a replacement string.
*
* @param s the original string
* @param regex the regex pattern to match
* @param replacement the replacement string
* @return the string with the last regex match replaced
*/
public static String replaceLast(String s, String regex, String replacement) {
return s.replaceFirst("(?s)(.*)" + regex, "$1" + replacement);
}
/**
* Replaces each occurrence of strings in the given array with corresponding replacement strings.
*
* @param s the original string
* @param occurrences the array of strings to be replaced
* @param replacements the array of replacement strings
* @return the string with all specified strings replaced
*/
public static String replaceEach(String s, String[] occurrences, String[] replacements) {
if (occurrences == null || replacements == null) return s;
for (int n = 0; n < occurrences.length && n < replacements.length; n++) {
s = replace(s, occurrences[n], replacements[n]);
}
return s;
}
/**
* Replaces all occurrences of a regex pattern in the given string with a replacement string.
*
* @param s the original string
* @param regex the regex pattern to match
* @param replacement the replacement string
* @return the string with all regex matches replaced
*/
public static String replaceAll(String s, String regex, String replacement) {
if (isNotNullOrEmpty(s) && replacement != null) return s.replaceAll(regex, replacement);
return s;
}
/**
* Replaces the content of a specific capturing group identified by its index in each match of a regex pattern
* within the string.
*
* @param s the original string
* @param regex the regex pattern containing the group
* @param groupIndex the index of the capturing group to replace
* @param replacement the replacement string
* @return the modified string
*/
public static String replaceGroup(String s, String regex, int groupIndex, String replacement) {
return replaceGroup(s, regex, groupIndex, 1, replacement);
}
/**
* Replaces a specific capturing group within a regex match in a string. If the regex has multiple matches,
* it targets the occurrence specified by {@code groupOccurrence}.
*
* @param s the original string
* @param regex the regular expression pattern containing the group
* @param groupIndex the index of the capturing group to replace
* @param groupOccurrence the occurrence of the match to target
* @param replacement the replacement string
* @return the modified string with the specified group replaced, or the original string if no match
* is found or parameters are invalid
*/
public static String replaceGroup(String s, String regex, int groupIndex, int groupOccurrence, String replacement) {
if (s == null || replacement == null) return s;
Matcher matcher = Pattern.compile(regex).matcher(s);
for (int i = 0; i < groupOccurrence; i++) {
if (!matcher.find()) return s;
}
if (groupIndex > matcher.groupCount() || matcher.group(groupIndex) == null) return s;
return new StringBuilder(s).replace(matcher.start(groupIndex), matcher.end(groupIndex), replacement).toString();
}
/**
* Replaces the start of the string matching a given prefix with a replacement string.
*
* @param s the original string
* @param prefix the prefix to match and replace
* @param replacement the replacement string
* @return the modified string
*/
public static String replaceStart(String s, String prefix, String replacement) {
if (startsWith(s, prefix) && replacement != null) return replacement + s.substring(prefix.length());
return s;
}
/**
* Replaces the start of the string with a replacement string if it starts with any of the given prefixes.
*
* @param s the original string
* @param replacement the replacement string
* @param prefixes an array of prefixes to check against the start of the string
* @return the string with the start replaced if it matches any of the prefixes, or the original string otherwise
*/
public static String replaceAnyStart(String s, String replacement, String... prefixes) {
for (String prefix : prefixes) {
if (startsWith(s, prefix)) return replaceStart(s, prefix, replacement);
}
return s;
}
/**
* Iteratively replaces the start of the string with the corresponding replacement if it matches
* any of the given prefixes.
*
* @param s the original string
* @param prefixes an array of prefixes to check against the start of the string
* @param replacements an array of replacement strings corresponding to each prefix
* @return the string with the start replaced if it matches any of the prefixes, or the original string otherwise
*/
public static String replaceEachStart(String s, String[] prefixes, String[] replacements) {
if (prefixes == null || replacements == null) return s;
for (int n = 0; n < prefixes.length && n < replacements.length; n++) {
String result = replaceStart(s, prefixes[n], replacements[n]);
if (!equals(s, result)) return result;
}
return s;
}
/**
* Replaces the end of the string matching a given suffix with a replacement string.
*
* @param s the original string
* @param suffix the suffix to match and replace
* @param replacement the replacement string
* @return the modified string
*/
public static String replaceEnd(String s, String suffix, String replacement) {
if (endsWith(s, suffix) && replacement != null)
return s.substring(0, s.length() - suffix.length()) + replacement;
return s;
}
/**
* Replaces the end of the string with a replacement string if it ends with any of the given suffixes.
*
* @param s the original string
* @param replacement the replacement string
* @param suffixes an array of suffixes to check against the end of the string
* @return the string with the end replaced if it matches any of the suffixes, or the original string otherwise
*/
public static String replaceAnyEnd(String s, String replacement, String... suffixes) {
for (String suffix : suffixes) {
if (endsWith(s, suffix)) return replaceEnd(s, suffix, replacement);
}
return s;
}
/**
* Iteratively replaces the end of the string with the corresponding replacement if it matches
* any of the given suffixes.
*
* @param s the original string
* @param suffixes an array of suffixes to check against the end of the string
* @param replacements an array of replacement strings corresponding to each suffix
* @return the string with the end replaced if it matches any of the suffixes, or the original string otherwise
*/
public static String replaceEachEnd(String s, String[] suffixes, String[] replacements) {
if (suffixes == null || replacements == null) return s;
for (int n = 0; n < suffixes.length && n < replacements.length; n++) {
String result = replaceEnd(s, suffixes[n], replacements[n]);
if (!equals(s, result)) return result;
}
return s;
}
/**
* Replaces the content between two specific characters in a string, while keeping the delimiters.
*
* @param s the original string
* @param opening the opening delimiter character
* @param closing the closing delimiter character
* @param replacement the string to replace the content between the delimiters
* @return the modified string, or the original if any of the delimiters is {@code null}
*/
public static String replaceBetweenChars(String s, char opening, char closing, String replacement) {
if (CharHelper.isNull(opening) || CharHelper.isNull(closing)) return s;
String regex = String.format("\\Q%1$s\\E.*?\\Q%2$s\\E", opening, closing);
return replaceAll(s, regex, opening + replacement + closing);
}
/**
* Replaces the content between two instances of the same delimiter character in a string,
* while keeping the delimiters.
*
* @param s the original string
* @param delimiter the character that acts as both the opening and closing delimiter
* @param replacement the string to replace the content between the delimiters
* @return the modified string, or the original if the delimiter is {@code null}
*/
public static String replaceBetweenChars(String s, char delimiter, String replacement) {
return replaceBetweenChars(s, delimiter, delimiter, replacement);
}
/**
* Replaces the content between parentheses in a string, while keeping the parentheses.
*
* @param s the original string
* @param replacement the string to replace content within parentheses
* @return the modified string with content within parentheses replaced
*/
public static String replaceBetweenParentheses(String s, String replacement) {
return replaceBetweenChars(s, '(', ')', replacement);
}
/**
* Replaces tags in the given string with their corresponding values from a map. Tags are in the format "${tag}".
*
* @param s the original string
* @param valuesMap a map containing tag-value pairs
* @return the string with all tags replaced by their corresponding values from the map
*/
public static String replaceTags(String s, Map valuesMap) {
if (isNullOrEmpty(s) || valuesMap == null) return s;
StringBuilder sb = new StringBuilder(s);
for (Map.Entry entry : valuesMap.entrySet()) {
int start;
String tag = "${" + entry.getKey() + "}";
String value = entry.getValue();
while ((start = sb.indexOf(tag)) != -1) {
sb.replace(start, start + tag.length(), value);
}
}
return sb.toString();
}
/**
* Removes all occurrences of a specified character from the string.
*
* @param s the original string
* @param occurrence the character to remove
* @return the string with all occurrences of the specified character removed
*/
public static String remove(String s, char occurrence) {
return replace(s, String.valueOf(occurrence), EMPTY);
}
/**
* Removes all occurrences of a specified substring from the string.
*
* @param s the original string
* @param occurrence the substring to remove
* @return the string with all occurrences of the specified substring removed
*/
public static String remove(String s, String occurrence) {
return replace(s, occurrence, EMPTY);
}
/**
* Removes a substring from the string, specified by start and end indices.
*
* @param s the original string
* @param startIndex the beginning index, inclusive
* @param endIndex the ending index, exclusive
* @return the string with the specified substring removed
*/
public static String removeByIndex(String s, int startIndex, int endIndex) {
return replaceByIndex(s, startIndex, endIndex, EMPTY);
}
/**
* Removes each occurrence of the specified substrings from the string.
*
* @param s the original string
* @param occurrences the substrings to remove
* @return the string with all specified substrings removed
*/
public static String removeEach(String s, String... occurrences) {
if (isNullOrEmpty(s) || occurrences == null) return s;
for (String occurrence : occurrences) {
if (isNotNullOrEmpty(occurrence)) s = replace(s, occurrence, EMPTY);
}
return s;
}
/**
* Removes all text that matches a given regular expression.
*
* @param s the original string
* @param regex the regular expression pattern that matches the text to remove
* @return the string with all matches removed
*/
public static String removeAll(String s, String regex) {
if (isNotNullOrEmpty(s) && isNotNullOrEmpty(regex)) return s.replaceAll(regex, EMPTY);
return s;
}
/**
* Removes a specific capturing group within a regex match in the string.
*
* @param s the original string
* @param regex the regular expression pattern containing the group
* @param groupIndex the index of the capturing group to remove
* @return the modified string with the specified group removed
*/
public static String removeGroup(String s, String regex, int groupIndex) {
return replaceGroup(s, regex, groupIndex, 1, EMPTY);
}
/**
* Removes the content of a specific capturing group identified by its index in a specific occurrence of a
* regex match within the string.
*
* @param s the original string
* @param regex the regular expression pattern containing the group
* @param groupIndex the index of the capturing group to remove
* @param groupOccurrence the occurrence of the group to target for removal
* @return the modified string with the specified group content removed
*/
public static String removeGroup(String s, String regex, int groupIndex, int groupOccurrence) {
return replaceGroup(s, regex, groupIndex, groupOccurrence, EMPTY);
}
/**
* Removes the first character of the string.
*
* @param s the original string
* @return the string with its first character removed
*/
public static String removeFirstChar(String s) {
if (isNotNullOrEmpty(s)) s = s.substring(1);
return s;
}
/**
* Removes the last character of the string.
*
* @param s the original string
* @return the string with its last character removed
*/
public static String removeLastChar(String s) {
if (isNotNullOrEmpty(s)) s = s.substring(0, s.length() - 1);
return s;
}
/**
* Removes the first occurrence of a specified substring from the string.
*
* @param s the original string
* @param occurrence the substring to remove
* @return the string with the first occurrence of the specified substring removed
*/
public static String removeOnce(String s, String occurrence) {
return replaceOnce(s, occurrence, EMPTY);
}
/**
* Removes the final occurrence of a specified substring from the string.
*
* @param s the original string
* @param occurrence the substring to remove
* @return the string with the final occurrence of the specified substring removed
*/
public static String removeFinal(String s, String occurrence) {
return replaceFinal(s, occurrence, EMPTY);
}
/**
* Removes the first occurrence of text that matches a given regular expression.
*
* @param s the original string
* @param regex the regular expression pattern that matches the text to remove
* @return the string with the first match removed
*/
public static String removeFirst(String s, String regex) {
return replaceFirst(s, regex, EMPTY);
}
/**
* Removes the last occurrence of text that matches a given regular expression.
*
* @param s the original string
* @param regex the regular expression pattern that matches the text to remove
* @return the string with the last match removed
*/
public static String removeLast(String s, String regex) {
return replaceLast(s, regex, EMPTY);
}
/**
* Removes the start of the string if it matches a given prefix.
*
* @param s the original string
* @param prefix the prefix to match and remove
* @return the string with the prefix removed
*/
public static String removeStart(String s, String prefix) {
return replaceStart(s, prefix, EMPTY);
}
/**
* Removes the start of the string if it matches any of the given prefixes.
*
* @param s the original string
* @param prefixes the prefixes to check and remove from the start of the string
* @return the string with any matching prefix removed
*/
public static String removeAnyStart(String s, String... prefixes) {
return replaceAnyStart(s, EMPTY, prefixes);
}
/**
* Removes the end of the string if it matches a given suffix.
*
* @param s the original string
* @param suffix the suffix to match and remove
* @return the string with the suffix removed
*/
public static String removeEnd(String s, String suffix) {
return replaceEnd(s, suffix, EMPTY);
}
/**
* Removes the end of the string if it matches any of the given suffixes.
*
* @param s the original string
* @param suffixes the suffixes to check and remove from the end of the string
* @return the string with any matching suffix removed
*/
public static String removeAnyEnd(String s, String... suffixes) {
return replaceAnyEnd(s, EMPTY, suffixes);
}
/**
* Removes the content between two specific characters in a string, including the delimiters.
*
* @param s the original string
* @param opening the opening delimiter character
* @param closing the closing delimiter character
* @return the modified string, or the original if any of the delimiters is {@code null}
*/
public static String removeWithinDelimiters(String s, char opening, char closing) {
if (CharHelper.isNull(opening) || CharHelper.isNull(closing)) return s;
String regex = String.format("\\Q%1$s\\E.*?\\Q%2$s\\E", opening, closing);
return s.replaceAll(regex, EMPTY);
}
/**
* Removes the content between two instances of the same delimiter character in a string, including the delimiters.
*
* @param s the original string
* @param delimiter the character that acts as both the opening and closing delimiter
* @return the modified string, or the original if the delimiter is {@code null}
*/
public static String removeWithinDelimiters(String s, char delimiter) {
return removeWithinDelimiters(s, delimiter, delimiter);
}
/**
* Removes the content between parentheses in a string, including the parentheses.
*
* @param s the original string
* @return the modified string
*/
public static String removeWithinParentheses(String s) {
return removeWithinDelimiters(s, '(', ')');
}
/**
* Returns the first character of the given string, or a {@code null} character if the string is {@code null} or empty.
*
* @param s the string from which to retrieve the first character
* @return the first character of the string, or the null character ({@code '\0'}) if the string is {@code null} or empty
*/
public static char getFirstChar(String s) {
if (isNotNullOrEmpty(s)) return s.charAt(0);
return CharHelper.NULL_CHAR;
}
/**
* Returns the last character of the given string, or a {@code null} character if the string is {@code null} or empty.
*
* @param s the string from which to retrieve the last character
* @return the last character of the string, or the null character ({@code '\0'}) if the string is {@code null} or empty
*/
public static char getLastChar(String s) {
if (isNotNullOrEmpty(s)) return s.charAt(s.length() - 1);
return CharHelper.NULL_CHAR;
}
/**
* Returns the first character of the given string as a String, or the original string if it is {@code null} or empty.
*
* @param s the string from which to retrieve the first character
* @return a String containing the first character, or the original string if it is {@code null} or empty
*/
public static String getStart(String s) {
if (isNotNullOrEmpty(s)) return String.valueOf(s.charAt(0));
return s;
}
/**
* Returns the last character of the given string as a String, or the original string if it is {@code null} or empty.
*
* @param s the string from which to retrieve the last character
* @return a String containing the last character, or the original string if it is {@code null} or empty
*/
public static String getEnd(String s) {
if (isNotNullOrEmpty(s)) return String.valueOf(s.charAt(s.length() - 1));
return s;
}
/**
* Returns the leftmost {@code n} characters of the given string, or the original string if {@code n}
* exceeds the string's length.
*
* @param s the string from which to extract characters
* @param n the number of characters to extract from the start of the string
* @return the leftmost {@code n} characters of {@code s}, or {@code s} itself if {@code n} is greater
* than the length of {@code s}
*/
public static String left(String s, int n) {
if (s == null || n < 0) return s;
else if (s.length() <= n) return s;
return s.substring(0, n);
}
/**
* Returns the rightmost {@code n} characters of the given string, or the original string if {@code n}
* exceeds the string's length.
*
* @param s the string from which to extract characters
* @param n the number of characters to extract from the end of the string
* @return the rightmost {@code n} characters of {@code s}, or {@code s} itself if {@code n}
* is greater than the length of {@code s}
*/
public static String right(String s, int n) {
if (s == null || n < 0) return s;
else if (s.length() <= n) return s;
return s.substring(s.length() - n);
}
/**
* Returns the substring of {@code s} that occurs before the last occurrence of the specified separator.
* If the separator is not found, returns the original string.
*
* @param s the string to search
* @param separator the string to search for
* @return the substring before the last occurrence of {@code separator}, or {@code s} itself
* if {@code separator} is not found
*/
public static String substringBeforeLast(final String s, final String separator) {
if (isNullOrEmpty(s) || isNullOrEmpty(separator)) return s;
int n = s.lastIndexOf(separator);
if (n == INDEX_NOT_FOUND) return s;
return s.substring(0, n);
}
/**
* Returns the substring of {@code s} that occurs after the last occurrence of the specified separator.
* If the separator is not found or is at the end of the string, returns the original string.
*
* @param s the string to search
* @param separator the string to search for
* @return the substring after the last occurrence of {@code separator}, or {@code s} itself if {@code separator}
* is not found or is at the end of {@code s}
*/
public static String substringAfterLast(final String s, final String separator) {
if (isNullOrEmpty(s) || isNullOrEmpty(separator)) return s;
int n = s.lastIndexOf(separator);
if (n == INDEX_NOT_FOUND || n == s.length() - separator.length()) return s;
return s.substring(n + 1);
}
/**
* Checks if two strings are equal, considering {@code null} values.
*
* @param a the first string
* @param b the second string
* @return {@code true} if the strings are equal, {@code false} otherwise
*/
public static boolean equals(String a, String b) {
return Objects.equals(a, b);
}
/**
* Checks if two strings are equal ignoring case, considering {@code null} values.
*
* @param a the first string
* @param b the second string
* @return {@code true} if the strings are equal ignoring case, {@code false} otherwise
*/
public static boolean equalsIgnoreCase(String a, String b) {
if (a == null || b == null) return equals(a, b);
return a.equalsIgnoreCase(b);
}
/**
* Checks if a string is equal to any of the specified occurrences, considering {@code null} values.
*
* @param s the string to check
* @param occurrences an array of strings to compare against
* @return {@code true} if the string is equal to any of the specified occurrences, {@code false} otherwise
*/
public static boolean equalsAny(String s, String... occurrences) {
if (s == null) return false;
for (String occurrence : occurrences) {
if (equals(s, occurrence)) return true;
}
return false;
}
/**
* Checks if a string is equal to the predefined default value.
*
* @param s the string to check
* @return {@code true} if the string is equal to {@value #DEFAULT_VALUE}, {@code false} otherwise
*/
public static boolean equalsDefault(String s) {
return equals(s, DEFAULT_VALUE);
}
/**
* Checks if a string starts with a specified character.
*
* @param s the string to check
* @param c the character to check at the start of the string
* @return {@code true} if the string starts with the specified character, {@code false} otherwise
*/
public static boolean startsWith(String s, char c) {
if (isNotNullOrEmpty(s) && !CharHelper.isNull(c)) return s.charAt(0) == c;
return CharHelper.isNull(c);
}
/**
* Checks if a string starts with a specified prefix.
*
* @param s the string to check
* @param prefix the prefix to check at the start of the string
* @return {@code true} if the string starts with the specified prefix, {@code false} otherwise
*/
public static boolean startsWith(String s, String prefix) {
if (isNotNullOrEmpty(s) && isNotNullOrEmpty(prefix) && s.length() >= prefix.length())
return s.indexOf(prefix) == 0;
return prefix == null;
}
/**
* Checks if a string starts with any of the specified characters.
*
* @param s the string to check
* @param chars an array of characters to check against the start of the string
* @return {@code true} if the string starts with any of the specified characters, {@code false} otherwise
*/
public static boolean startsWithAny(String s, char... chars) {
for (char c : chars) {
if (startsWith(s, c)) return true;
}
return false;
}
/**
* Checks if a string starts with any of the specified prefixes.
*
* @param s the string to check
* @param prefixes an array of prefixes to check against the start of the string
* @return {@code true} if the string starts with any of the specified prefixes, {@code false} otherwise
*/
public static boolean startsWithAny(String s, String... prefixes) {
for (String prefix : prefixes) {
if (startsWith(s, prefix)) return true;
}
return false;
}
/**
* Checks if a string ends with a specified character.
*
* @param s the string to check
* @param c the character to check at the end of the string
* @return {@code true} if the string ends with the specified character, {@code false} otherwise
*/
public static boolean endsWith(String s, char c) {
if (isNotNullOrEmpty(s) && !CharHelper.isNull(c)) return s.charAt(s.length() - 1) == c;
return CharHelper.isNull(c);
}
/**
* Checks if a string ends with a specified suffix.
*
* @param s the string to check
* @param suffix the suffix to check at the end of the string
* @return {@code true} if the string ends with the specified suffix, {@code false} otherwise
*/
public static boolean endsWith(String s, String suffix) {
if (isNotNullOrEmpty(s) && isNotNullOrEmpty(suffix) && s.length() >= suffix.length()) return s.endsWith(suffix);
return suffix == null;
}
/**
* Checks if a string ends with any of the specified characters.
*
* @param s the string to check
* @param chars an array of characters to check against the end of the string
* @return {@code true} if the string ends with any of the specified characters, {@code false} otherwise
*/
public static boolean endsWithAny(String s, char... chars) {
for (char c : chars) {
if (endsWith(s, c)) return true;
}
return false;
}
/**
* Checks if a string ends with any of the specified suffixes.
*
* @param s the string to check
* @param suffixes an array of suffixes to check against the end of the string
* @return {@code true} if the string ends with any of the specified suffixes, {@code false} otherwise
*/
public static boolean endsWithAny(String s, String... suffixes) {
for (String suffix : suffixes) {
if (endsWith(s, suffix)) return true;
}
return false;
}
/**
* Checks if the given string contains the specified character.
*
* @param s the string to check
* @param c the character to find
* @return {@code true} if the character is found in the string, {@code false} otherwise
*/
public static boolean has(String s, char c) {
return indexOf(s, c) != -1;
}
/**
* Checks if the given string contains the specified substring.
*
* @param s the string to check
* @param occurrence the substring to find
* @return {@code true} if the substring is found in the string, {@code false} otherwise
*/
public static boolean has(String s, String occurrence) {
return indexOf(s, occurrence) != -1;
}
/**
* Checks if the given string contains any of the specified characters.
*
* @param s the string to check
* @param chars the characters to find
* @return {@code true} if any of the characters are found in the string, {@code false} otherwise
*/
public static boolean hasAny(String s, char... chars) {
if (isNullOrEmpty(s)) return false;
for (char character : chars) {
for (char c : s.toCharArray()) {
if (c == character) return true;
}
}
return false;
}
/**
* Checks if the given string contains any of the specified affixes.
*
* @param s the string to check
* @param affixes the affixes to find
* @return {@code true} if any of the affixes are found in the string, {@code false} otherwise
*/
public static boolean hasAny(String s, String... affixes) {
if (isNullOrEmpty(s) || ArrayHelper.isNullOrEmpty(affixes)) return false;
for (String affix : affixes) {
if (affix != null && s.contains(affix)) return true;
}
return false;
}
/**
* Escapes special characters in a Java String using escape sequences.
*
* This method processes the input string and applies escape sequences to special characters,
* such as the backslash (\), newline (\n), and others, making the string safe for use in Java source code.
*
* Supported escape sequences include:
*
* - \\ (backslash)
* - \b (backspace)
* - \f (form feed)
* - \n (newline)
* - \r (carriage return)
* - \t (horizontal tab)
* - \' (single quote)
* - \" (double quote)
*
*
* @param s the string to escape
* @return the escaped string, or {@code null} if the input string is {@code null}
*/
public static String escapeJavaString(String s) {
if (s == null) return null;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
switch (c) {
case '\\' -> sb.append("\\\\");
case '\b' -> sb.append("\\b");
case '\f' -> sb.append("\\f");
case '\n' -> sb.append("\\n");
case '\r' -> sb.append("\\r");
case '\t' -> sb.append("\\t");
case '\'' -> sb.append("\\'");
case '\"' -> sb.append("\\\"");
default -> sb.append(c);
}
}
return sb.toString();
}
/**
* Unescapes a string that contains standard Java escape sequences.
*
* - \b \f \n \r \t \" \' :
* BS, FF, NL, CR, TAB, double and single quote.
* - \X \XX \XXX : Octal character
* specification (0 - 377, 0x00 - 0xFF).
* - \uXXXX : Hexadecimal based Unicode character.
*
*
* @param st a string optionally containing standard java escape sequences
* @return the translated string
*/
public static String unescapeJavaString(String st) {
if (isNullOrEmpty(st)) return st;
StringBuilder sb = new StringBuilder(st.length());
for (int i = 0; i < st.length(); i++) {
char ch = st.charAt(i);
if (ch == '\\') {
char nextChar = (i == st.length() - 1) ? '\\' : st.charAt(i + 1);
// Octal escape?
if (nextChar >= '0' && nextChar <= '7') {
String code = EMPTY + nextChar;
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0' && st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
if ((i < st.length() - 1) && st.charAt(i + 1) >= '0' && st.charAt(i + 1) <= '7') {
code += st.charAt(i + 1);
i++;
}
}
sb.append((char) Integer.parseInt(code, 8));
continue;
}
switch (nextChar) {
case '\\' -> ch = '\\';
case 'b' -> ch = '\b';
case 'f' -> ch = '\f';
case 'n' -> ch = '\n';
case 'r' -> ch = '\r';
case 't' -> ch = '\t';
case '\"' -> ch = '\"';
case '\'' -> ch = '\'';
// Hex Unicode: u????
case 'u' -> {
if (i >= st.length() - 5) {
ch = 'u';
break;
}
int code = Integer.parseInt(EMPTY + st.charAt(i + 2) + st.charAt(i + 3) + st.charAt(i + 4) + st.charAt(i + 5), 16);
sb.append(Character.toChars(code));
i += 5;
continue;
}
}
i++;
}
sb.append(ch);
}
return sb.toString();
}
/**
* Converts a character to its Unicode escape string.
*
* @param c the character to convert
* @return the Unicode escape string of the character, or {@code null} if the character is the null character ({@code '\0'})
*/
public static String getUnicode(char c) {
if (!CharHelper.isNull(c)) return String.format("\\u%04x", (int) c);
return null;
}
/**
* Constructs a string from an array of Unicode code points.
*
* @param codePoints an array of Unicode code points
* @return the string constructed from the code points
*/
public static String getCharacter(String... codePoints) {
StringBuilder sb = new StringBuilder();
for (String codePoint : codePoints) {
if (isNotNullOrBlank(codePoint) && Validation.isUtf(codePoint))
sb.appendCodePoint(Integer.decode(codePoint.replace("U+", "0x")));
}
return sb.toString();
}
/**
* Creates a hex color string in ARGB format from the given alpha, red, green, and blue values.
*
* @param alpha the alpha component
* @param red the red component
* @param green the green component
* @param blue the blue component
* @return the ARGB hex color string
*/
public static String getHexStringFromARGB(int alpha, int red, int green, int blue) {
if ((alpha < 0 || alpha > 255) || (red < 0 || red > 255) || (green < 0 || green > 255) || (blue < 0 || blue > 255))
return ("#FFFFFFFF");
return String.format("#%02X%02X%02X%02X", alpha, red, green, blue).toUpperCase();
}
/**
* Generates a hash code for the given string.
*
* This method calculates a hash code for the input string using a modified version of the
* well-known DJB2 algorithm. The hash code is generated by iterating over each character
* in the string and applying a series of bitwise operations to accumulate the final hash
* value.
*
* @param s the string to calculate the hash code for
* @return the hash code for the input string, or {@code null} if the string is {@code null} or empty
*/
public static Long hashcode(String s) {
if (isNullOrEmpty(s)) return null;
long hash = 0;
for (char c : s.toCharArray()) {
hash = 31L * hash + c;
}
return hash;
}
/**
* Computes the hash of the given string using the specified algorithm.
*
* @param s the string to hash
* @param algorithm the name of the hash algorithm to use (e.g., "MD5", "SHA-256", "SHA-512")
* @return the hash value of the string, or {@code null} if an error occurs or the algorithm is invalid
*/
public static String hash(String s, String algorithm) {
if (s == null || isNullOrEmpty(algorithm)) return null;
try {
final MessageDigest md = MessageDigest.getInstance(algorithm);
final byte[] hashBytes = md.digest(s.getBytes(StandardCharsets.UTF_8));
final StringBuilder sb = new StringBuilder(hashBytes.length * 2);
for (byte b : hashBytes) {
sb.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);
}
return sb.toString();
} catch (Exception ignored) {
}
return null;
}
/**
* Generates an MD5 hash of the given string.
*
* @param s the string to hash
* @return the MD5 hash of the string, or an empty string if an error occurs
*/
public static String md5(String s) {
return hash(s, "MD5");
}
/**
* Generates an SHA-256 hash of the given string.
*
* @param s the string to hash
* @return the SHA-256 hash of the string, or {@code null} if an error occurs
*/
public static String sha256(final String s) {
return hash(s, "SHA-256");
}
/**
* Generates an SHA-512 hash of the given string.
*
* @param s the string to hash
* @return the SHA-512 hash of the string, or {@code null} if an error occurs
*/
public static String sha512(final String s) {
return hash(s, "SHA-512");
}
}