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

io.github.atkawa7.caseutils.StringUtil Maven / Gradle / Ivy

The newest version!
package io.github.atkawa7.caseutils;

import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static java.lang.Character.*;
import static org.apache.commons.lang3.StringUtils.*;


/**
 * @author Olivier Smedile
 * @version $Id: StringUtil.java 62 2008-04-20 11:11:54Z osmedile $
 */
public class StringUtil {
    public static final Pattern NUMBERS = Pattern.compile("^[ ,.\\-+\\d]*\\d[ ,.\\-+\\d%]*$");
    public static final char EMPTY_CHAR = 0;

    public static String removeAllSpace(String s) {
        return join(s.split("\\s"), "").trim();
    }

    public static String trimAllSpace(String s) {
        return join(s.split("\\s+"), " ");
    }

    public static String camelToText(String s, Separator separator) {
        StringBuilder buf = new StringBuilder();
        char lastChar = ' ';
        for (char c : s.toCharArray()) {
            char nc = c;
            if (isUpperCase(nc) && isLowerCase(lastChar)) {
                buf.append(" ");
                nc = Character.toLowerCase(c);
            } else if ((separator.isSeparatorAfterDigit() && isDigit(lastChar) && isLetter(c))
                    || (separator.isSeparatorBeforeDigit() && isDigit(c) && isLetter(lastChar))) {
                if (lastChar != ' ') {
                    buf.append(" ");
                }
                nc = Character.toLowerCase(c);
            }

            if (lastChar != ' ' || c != ' ') {
                buf.append(nc);
            }
            lastChar = c;
        }
        return buf.toString();
    }

    /**
     * inspired by org.apache.commons.text.WordUtils#capitalize
     */
    public static String capitalizeFirstWord(String str, char[] delimiters) {
        if (isEmpty(str)) {
            return str;
        } else {
            boolean done = false;
            Set delimiterSet = generateDelimiterSet(delimiters);
            int strLen = str.length();
            int[] newCodePoints = new int[strLen];
            int outOffset = 0;
            boolean capitalizeNext = true;
            int index = 0;

            while (index < strLen) {
                int codePoint = str.codePointAt(index);
                if (delimiterSet.contains(codePoint)) {
                    capitalizeNext = true;
                    newCodePoints[outOffset++] = codePoint;
                    index += Character.charCount(codePoint);
                } else if (!done && capitalizeNext && isLowerCase(codePoint)) {
                    int titleCaseCodePoint = Character.toTitleCase(codePoint);
                    newCodePoints[outOffset++] = titleCaseCodePoint;
                    index += Character.charCount(titleCaseCodePoint);
                    capitalizeNext = false;
                    done = true;
                } else {
                    newCodePoints[outOffset++] = codePoint;
                    index += Character.charCount(codePoint);
                }
            }

            return new String(newCodePoints, 0, outOffset);
        }
    }

    public static String capitalizeFirstWord2(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            StringBuilder buf = new StringBuilder();
            boolean upperNext = true;
            char[] chars = str.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                char c = chars[i];
                if (isLetter(c) && upperNext) {
                    buf.append(toUpperCase(c));
                    upperNext = false;
                } else {
                    if (!isLetterOrDigit(c)) {
                        upperNext = true;
                    }
                    buf.append(c);
                }

            }

            return buf.toString();
        }
    }

    /**
     * org.apache.commons.text.WordUtils.generateDelimiterSet
     */
    public static Set generateDelimiterSet(char[] delimiters) {
        Set delimiterHashSet = new HashSet();
        if (delimiters != null && delimiters.length != 0) {
            for (int index = 0; index < delimiters.length; ++index) {
                delimiterHashSet.add(Character.codePointAt(delimiters, index));
            }

            return delimiterHashSet;
        } else {
            if (delimiters == null) {
                delimiterHashSet.add(Character.codePointAt(new char[]{' '}, 0));
            }

            return delimiterHashSet;
        }
    }

    public static String toSoftCamelCase(String s) {
        String[] words = s.split("[\\s_]");


        for (int i = 0; i < words.length; i++) {
            words[i] = StringUtils.capitalize(words[i]);
        }

        return join(words);
    }


    public static String toCamelCase(String s) {
        String[] words = splitByCharacterTypeCamelCase(s);

        boolean firstWord = true;
        for (int i = 0; i < words.length; i++) {
            String word = words[i];
            if (firstWord && startsWithLetter(word)) {
                words[i] = word.toLowerCase();
                firstWord = false;
                if (i > 1 && isBlank(words[i - 1]) && isAllLetterOrDigit(words[i - 2])) {
                    words[i - 1] = "";
                }
            } else if (specialWord(word)) { // multiple camelCases
                firstWord = true;
            } else {
                words[i] = StringUtils.capitalize(word.toLowerCase());
                if (i > 1 && isBlank(words[i - 1]) && isAllLetterOrDigit(words[i - 2])) {
                    words[i - 1] = "";
                }
            }
        }
        String join = join(words);
        join = replaceSeparatorBetweenLetters(join, '_', EMPTY_CHAR);
        join = replaceSeparatorBetweenLetters(join, '-', EMPTY_CHAR);
        join = replaceSeparatorBetweenLetters(join, '.', EMPTY_CHAR);
        return join;
    }

    private static boolean isAllLetterOrDigit(String word) {
        for (char c : word.toCharArray()) {
            if (!isLetterOrDigit(c)) {
                return false;
            }
        }
        return true;
    }

    private static boolean specialWord(String word) {
        if (isBlank(word)) {
            return false;
        }
        for (char c : word.toCharArray()) {
            if (isDigit(c) || isLetter(c) || isSeparator(c)) {
                return false;
            }
        }
        return true;
    }

    private static boolean startsWithLetter(String word) {
        return word.length() > 0 && isLetter(word.charAt(0));
    }

    private static boolean isNotQuote(String word) {
        return !"\"".equals(word) && !"\'".equals(word);
    }

    public static String wordsToConstantCase(String s) {
        StringBuilder buf = new StringBuilder();

        char lastChar = 'a';
        for (char c : s.toCharArray()) {
            if (isWhitespace(lastChar) && (!isWhitespace(c) && '_' != c) &&
                    buf.length() > 0 && buf.charAt(buf.length() - 1) != '_') {
                buf.append("_");
            }
            if (!isWhitespace(c)) {
                buf.append(Character.toUpperCase(c));

            }
            lastChar = c;
        }
        if (isWhitespace(lastChar)) {
            buf.append("_");
        }


        return buf.toString();

    }


    public static class Separator{
        private boolean separatorAfterDigit;
        private boolean separatorBeforeDigit;
        private boolean separatorBetweenUppercases;

        public boolean isSeparatorAfterDigit() {
            return separatorAfterDigit;
        }

        public void setSeparatorAfterDigit(boolean separatorAfterDigit) {
            this.separatorAfterDigit = separatorAfterDigit;
        }

        public boolean isSeparatorBeforeDigit() {
            return separatorBeforeDigit;
        }

        public void setSeparatorBeforeDigit(boolean separatorBeforeDigit) {
            this.separatorBeforeDigit = separatorBeforeDigit;
        }

        public boolean isSeparatorBetweenUppercases() {
            return separatorBetweenUppercases;
        }

        public void setSeparatorBetweenUppercases(boolean separatorBetweenUppercases) {
            this.separatorBetweenUppercases = separatorBetweenUppercases;
        }
    }

    public static String wordsAndHyphenAndCamelToConstantCase(String s, Separator separator) {
        boolean containsLowerCase = containsLowerCase(s);

        StringBuilder buf = new StringBuilder();
        char previousChar = ' ';
        char[] chars = s.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            char c = chars[i];
            boolean isUpperCaseAndPreviousIsUpperCase = isUpperCase(previousChar) && isUpperCase(c);
            boolean isUpperCaseAndPreviousIsLowerCase = isLowerCase(previousChar) && isUpperCase(c);
            // boolean isLowerCaseLetter = !isWhitespace(c) && '_' != c && !isUpperCase(c);
            // boolean isLowerCaseAndPreviousIsWhitespace = isWhitespace(lastChar) && isLowerCaseLetter;
//			boolean previousIsWhitespace = isWhitespace(previousChar);
//			boolean lastOneIsNotUnderscore = buf.length() > 0 && buf.charAt(buf.length() - 1) != '_';
//			boolean isNotUnderscore = c != '_';
            //  ORIGINAL      if (lastOneIsNotUnderscore && (isUpperCase(c) || isLowerCaseAndPreviousIsWhitespace)) {

            //camelCase handling - add extra _
            if (isLetter(c) && isLetter(previousChar) &&
                    (
                            isUpperCaseAndPreviousIsLowerCase
                                    || (containsLowerCase && separator.isSeparatorBetweenUppercases() && isUpperCaseAndPreviousIsUpperCase)
                    )
            ) {
                buf.append("_");
                // extra _ after number
            } else if ((separator.isSeparatorAfterDigit() && isDigit(previousChar) && isLetter(c))
                    || (separator.isSeparatorBeforeDigit() && isDigit(c) && isLetter(previousChar))) {
                buf.append('_');
            }


            //replace separators by _
            if ((isSeparator(c) || isWhitespace(c)) && isLetterOrDigit(previousChar) && nextIsLetterOrDigit(s, i)) {
                buf.append('_');
            } else {
                buf.append(Character.toUpperCase(c));
            }

            previousChar = c;
        }
//		if (isWhitespace(previousChar)) {
//			buf.append("_");
//		}


        return buf.toString();
    }


    private static boolean betweenLettersOrDigits(char[] chars, int i) {
        for (int j = i; j < chars.length; j++) {
            char aChar = chars[j];
            if (!isLetterOrDigit(aChar) && !isWhitespace(aChar)) {
                return false;
            }
            if (isLetterOrDigit(aChar)) {
                break;
            }
        }
        for (int j = i; j >= 0; j--) {
            char aChar = chars[j];
            if (!isLetterOrDigit(aChar) && !isWhitespace(aChar)) {
                return false;
            }
            if (isLetterOrDigit(aChar)) {
                break;
            }
        }
        return true;
    }

    private static boolean isSlash(char c) {
        return c == '\\' || c == '/';
    }

    private static boolean isNotBorderQuote(char actualChar, int i, char[] chars) {
        if (chars.length - 1 == i) {
            char firstChar = chars[0];
            if (isQuote(actualChar) && isQuote(firstChar)) {
                return true;
            }
        }
        return false;
    }

    private static boolean isQuote(char actualChar) {
        return actualChar == '\'' || actualChar == '\"';
    }

    public static String toDotCase(String s, Separator separator) {
        StringBuilder buf = new StringBuilder();

        char lastChar = ' ';
        for (char c : s.toCharArray()) {
            boolean isUpperCaseAndPreviousIsLowerCase = isLowerCase(lastChar) && isUpperCase(c);
            boolean previousIsWhitespace = isWhitespace(lastChar);
            boolean lastOneIsNotUnderscore = buf.length() > 0 && buf.charAt(buf.length() - 1) != '.';
            if (lastOneIsNotUnderscore && (isUpperCaseAndPreviousIsLowerCase || previousIsWhitespace)) {
                buf.append(".");
            } else if ((separator.isSeparatorAfterDigit() && isDigit(lastChar) && isLetter(c))
                    || (separator.isSeparatorBeforeDigit() && isDigit(c) && isLetter(lastChar))) {
                buf.append(".");
            }

            if (c == '.') {
                buf.append('.');
            } else if (c == '-') {
                buf.append('.');
            } else if (c == '_') {
                buf.append('.');
            } else if (!isWhitespace(c)) {
                buf.append(Character.toLowerCase(c));
            }

            lastChar = c;
        }
        if (isWhitespace(lastChar)) {
            buf.append(".");
        }


        return buf.toString();
    }

    @NotNull
    public static String replaceSeparator(String s1, char s, char s2) {
        return s1.replace(s, s2);
    }

    @NotNull
    public static String replaceSeparatorBetweenLetters(String s, char from, char to) {
        StringBuilder buf = new StringBuilder();
        char lastChar = ' ';
        char[] charArray = s.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
            if (c == from) {
                boolean lastDigit = isDigit(lastChar);
                boolean lastLetterOrDigit = isLetterOrDigit(lastChar);
                boolean nextDigit = nextIsDigit(s, i);
                boolean nextLetterOrDigit = nextIsLetterOrDigit(s, i);

                if (lastDigit && nextDigit) {
                    buf.append(c);
                } else if (lastLetterOrDigit && nextLetterOrDigit) {
                    if (to != EMPTY_CHAR) {
                        buf.append(to);
                    }
                } else {
                    buf.append(c);
                }
            } else {
                buf.append(c);
            }
            lastChar = c;
        }

        return buf.toString();
    }

    private static boolean nextIsDigit(String s, int i) {
        if (i + 1 >= s.length()) {
            return false;
        } else {
            return Character.isDigit(s.charAt(i + 1));
        }
    }

    private static boolean nextIsLetterOrDigit(String s, int i) {
        if (i + 1 >= s.length()) {
            return false;
        } else {
            return Character.isLetterOrDigit(s.charAt(i + 1));
        }
    }

    private static boolean nextIsLetter(String s, int i) {
        if (i + 1 >= s.length()) {
            return false;
        } else {
            return Character.isLetter(s.charAt(i + 1));
        }
    }

    /**
     * 

Splits the given input sequence around matches of this pattern.

*

*

The array returned by this method contains each substring of the input sequence * that is terminated by another subsequence that matches this pattern or is terminated by * the end of the input sequence. * The substrings in the array are in the order in which they occur in the input. * If this pattern does not match any subsequence of the input then the resulting array * has just one element, namely the input sequence in string form.

*

*

     * splitPreserveAllTokens("boo:and:foo", ":") =  { "boo", ":", "and", ":", "foo"}
     * splitPreserveAllTokens("boo:and:foo", "o") =  { "b", "o", "o", ":and:f", "o", "o"}
     * 
* * @param input The character sequence to be split * @return The array of strings computed by splitting the input around matches of this pattern */ public static String[] splitPreserveAllTokens(String input, String regex) { int index = 0; Pattern p = Pattern.compile(regex); ArrayList result = new ArrayList(); Matcher m = p.matcher(input); // Add segments before each match found int lastBeforeIdx = 0; while (m.find()) { if (isNotEmpty(m.group())) { String match = input.subSequence(index, m.start()).toString(); if (isNotEmpty(match)) { result.add(match); } result.add(input.subSequence(m.start(), m.end()).toString()); index = m.end(); } } // If no match was found, return this if (index == 0) { return new String[]{input}; } final String remaining = input.subSequence(index, input.length()).toString(); if (isNotEmpty(remaining)) { result.add(remaining); } // Construct result return result.toArray(new String[result.size()]); } public static String nonAsciiToUnicode(String s) { StringBuffer sb = new StringBuffer(s.length()); for (Character c : s.toCharArray()) { if (!CharUtils.isAscii(c)) { sb.append(CharUtils.unicodeEscaped(c)); } else { sb.append(c); } } return sb.toString(); } public static String escapedUnicodeToString(String s) { String[] parts = StringUtil.splitPreserveAllTokens(s, "\\\\u[0-9a-fA-F]{4}"); for (int i = 0; i < parts.length; i++) { if (parts[i].startsWith("\\u")) { int v = Integer.parseInt(parts[i].substring(2), 16); parts[i] = "" + ((char) v); } } return join(parts); } public static String wordsToHyphenCase(String s) { StringBuilder buf = new StringBuilder(); char lastChar = 'a'; for (char c : s.toCharArray()) { if (isWhitespace(lastChar) && (!isWhitespace(c) && '-' != c) && buf.length() > 0 && buf.charAt(buf.length() - 1) != '-') { buf.append("-"); } if ('_' == c) { buf.append('-'); } else if ('.' == c) { buf.append('-'); } else if (!isWhitespace(c)) { buf.append(toLowerCase(c)); } lastChar = c; } if (isWhitespace(lastChar)) { buf.append("-"); } return buf.toString(); } public static boolean containsLowerCase(String s) { for (char c : s.toCharArray()) { if (isLowerCase(c)) { return true; } } return false; } public static int indexOfAnyButWhitespace(String cs) { if (isEmpty(cs)) { return cs.length(); } final int csLen = cs.length(); for (int i = 0; i < csLen; i++) { final char ch = cs.charAt(i); if (isWhitespace(ch)) { continue; } return i; } return cs.length(); } public static String substringUntilSpecialCharacter(String s) { int firstLetterOrDigitOrSeparator = -1; char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (!isLetterOrDigit(c) && !isWhitespace(c) && !isSeparator(c) && firstLetterOrDigitOrSeparator != -1) { return s.substring(firstLetterOrDigitOrSeparator, i); } if (isLetterOrDigit(c) || isWhitespace(c) || isSeparator(c)) { if (firstLetterOrDigitOrSeparator == -1) { firstLetterOrDigitOrSeparator = i; } } } return s; } public static boolean isSeparator(char c) { return c == '.' || c == '-' || c == '_'; } public static boolean containsOnlyLettersAndDigits(String s) { for (char c : s.toCharArray()) { if (!isLetterOrDigit(c)) { return false; } } return true; } public static boolean noUpperCase(String s) { for (char c : s.toCharArray()) { if (Character.isUpperCase(c)) { return false; } } return true; } public static String removeBorderQuotes(String s) { if (isQuoted(s)) { s = s.substring(1, s.length() - 1); } return s; } public static boolean isQuoted(String selectedText) { return selectedText != null && selectedText.length() > 2 && (isBorderChar(selectedText, "\"") || isBorderChar(selectedText, "\'")); } public static boolean isBorderChar(String s, String borderChar) { return s.startsWith(borderChar) && s.endsWith(borderChar); } public static boolean noLowerCase(String s) { for (char c : s.toCharArray()) { if (Character.isLowerCase(c)) { return false; } } return true; } public static boolean containsUpperCase(String s) { for (char c : s.toCharArray()) { if (Character.isUpperCase(c)) { return true; } } return false; } public static boolean containsUpperCaseAfterLowerCase(String s) { char previous = ' '; char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (isUpperCase(c) && isLetter(previous) && isLowerCase(previous)) { return true; } previous = c; } return false; } public static boolean isCapitalizedFirstButNotAll(String str) { if (str.length() == 0) { return false; } Set delimiterSet = generateDelimiterSet(new char[]{' '}); int strLen = str.length(); int index = 0; int firstCapitalizedIndex = -1; boolean someUncapitalized = false; boolean afterSeparatorOrFirst = true; while (index < strLen) { int codePoint = str.codePointAt(index); // char c = str.charAt(index); if (delimiterSet.contains(codePoint)) { afterSeparatorOrFirst = true; } else { if (isLowerCase(codePoint) && afterSeparatorOrFirst) { if (firstCapitalizedIndex == -1) { return false; } someUncapitalized = true; afterSeparatorOrFirst = false; } else if (isUpperCase(codePoint) && afterSeparatorOrFirst) { if (firstCapitalizedIndex == -1) { firstCapitalizedIndex = index; } afterSeparatorOrFirst = false; } } index += charCount(codePoint); } return firstCapitalizedIndex != -1 && someUncapitalized; } public static boolean firstLetterUpperCase(String s) { char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (isLetter(c)) { if (isLowerCase(c)) { return false; } else if (isUpperCase(c)) { return true; } } } return false; } public static boolean firstLetterLowerCase(String s) { char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (isLetter(c)) { if (isLowerCase(c)) { return true; } else if (isUpperCase(c)) { return false; } } } return false; } public static boolean noSeparators(String s, char... delimiters) { if (s.length() == 0) { return true; } Set delimiterSet = generateDelimiterSet(delimiters); boolean letterFound = false; char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (isLetterOrDigit(c)) { letterFound = true; continue; } if (letterFound && delimiterSet.contains((int) c)) { return false; } } return true; } public static boolean containsSeparatorBetweenLetters(String s, char separator) { char previous = '?'; char[] charArray = s.toCharArray(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; if (c == separator && isLetterOrDigit(previous) && nextIsLetterOrDigit(s, i)) { return true; } previous = c; } return false; } @NotNull public static List splitToTokensBySpace(String originalText) { char[] chars = originalText.toCharArray(); List result = new ArrayList<>(); int whiteSpaceBeginning = -1; int tokenBeginning = -1; for (int i = 0; i < chars.length; i++) { char aChar = chars[i]; if (aChar == ' ') { if (whiteSpaceBeginning == -1) { whiteSpaceBeginning = i; } if (tokenBeginning != -1) { result.add(new String(Arrays.copyOfRange(chars, tokenBeginning, i))); tokenBeginning = -1; } } else { if (whiteSpaceBeginning != -1) { result.add(new String(Arrays.copyOfRange(chars, whiteSpaceBeginning, i))); whiteSpaceBeginning = -1; } if (tokenBeginning == -1) { tokenBeginning = i; } } } if (tokenBeginning != -1) { result.add(new String(Arrays.copyOfRange(chars, tokenBeginning, chars.length))); } if (whiteSpaceBeginning != -1) { result.add(new String(Arrays.copyOfRange(chars, whiteSpaceBeginning, chars.length))); } return result; } public static String toSpringEnvVariable(String s) { return Arrays.stream(split(s, ".")) .map(StringUtils::trim) .map(str -> StringUtils.replaceChars(str, "-", "")) .map(str -> StringUtils.replaceChars(str, "_", "")) .collect(Collectors.joining("_")) .toUpperCase(); } public static boolean isCapitalizedFully(String s, char separator) { boolean result = false; char prev = 0; for (char c1 : s.toCharArray()) { boolean shouldBeUpper = (prev == 0 || prev == separator); if (!isLetter(c1)) { //skip } else if ((shouldBeUpper && isUpperCase(c1)) || (!shouldBeUpper && isLowerCase(c1))) { result = true; } else { return false; } prev = c1; } return result; } public static class Constants { public static final char[] DELIMITERS = new char[]{'\'', '\"', ' '}; } public static String rightAlign(String input, int textLength) { if (textLength <= 0) { return input; } return String.format("%" + textLength + "s", input); } public static String rightAlignNumber(String input, int textLength) { if (textLength <= 0) { return input; } boolean isNumber = isNumber(input); if (!isNumber) { return input; } return String.format("%" + textLength + "s", input); } public static boolean isNumber(String input) { return NUMBERS.matcher(input).matches(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy