zoukankan      html  css  js  c++  java
  • StringUtils

    StringUtils

    对String功能的补充(null安全)包括查询 判断 截取 去除 分组 替换 等功能,又加入各种简明的关键词对功能进行加强,大部分功能都很简单,实现的种类也很齐全

    关键词:

    Not:boolean求反

    Empty:空对象   Empty,空对象,拥有null的意义却没有null的bug

    NULL:null       Null,关键字,跟绝大多数bug沾亲带故

    Start:字符串开头

    End:字符串结尾

    Whitespace:空格,包含全角,半角以及各种带有空格的操作码(/t。。)

    IgnoreCase:忽视大小写

    last:最后一位

    Any:将String转为char[]后中的任意一个

    But:对其他关键字取反

    Only:仅仅

    None:取反

    Between:有left 有right就有可能有Between

    代码版本:apache.commons.lang3.0

    1.判断

    isEmpty:判断是否为空

    isBlank:是否空白

    countMatches(CharSequence str, CharSequence sub):匹配次数

    isAlpha:仅包括字符(Alpha为字母,不过本地话以后可以理解为字符)

    isAlphaSpace:允许为半角空格

    isAlphanumeric:允许为数字

    isAlphanumericSpace,isAsciiPrintable,isNumeric,isNumericSpace,isWhitespace,isAllLowerCase,isAllUpperCase等

    contains,equal 等

        public static boolean isEmpty(CharSequence cs) {//3.0之前为String
            return cs == null || cs.length() == 0;
        }//实现CharSequence 接口的有CharBuffer、String、StringBuffer、StringBuilder
        public static boolean isBlank(CharSequence cs) {
            int strLen;
            if (cs == null || (strLen = cs.length()) == 0) {
                return true;
            }
            for (int i = 0; i < strLen; i++) {
                if (Character.isWhitespace(cs.charAt(i)) == false) {
                    return false;
                }
            }
            return true;
        }
    ... 
    for (int i = 0; i < sz; i++) {
                if (Character.isLetter(cs.charAt(i)) == false) { //简单的理解为字母+方言(比如中文)
                    return false;
                }
            }
    ...//isAlphaSpace
    if (Character.isLetter(cs.charAt(i)) == false && cs.charAt(i) != ' ') {//半角空格
                    return false;
                }
    ...//isNumeric
    for (int i = 0; i < sz; i++) {
                if (Character.isDigit(cs.charAt(i)) == false) { //循环判断数字,故带+/-/.的全pass,另外大多判断都是如此
                        return false;                           //,故加入特殊方法
                }
            }

    补充:半角空格与全角空格字节码不一样,trim直接与半角空格作比较(val[off + st] <= ' '),即与assic码比较

             isWhitespace则做了更多的判断,总之,结论如下

    1.Character.isWhitespace() 全角和半角空格都为空格,即返回true
    2.Character.isSpaceChar()  全角和半角空格都为空格,即返回true
    3.Character.isSpace() 半角空格为空格,即半角空格返回true,全角空格返回false,但此方法被废弃
    4.trim()只截取掉半角的空格(全角空格与编码有关,估计当时只有assic上哪几种空格表示方式)

    2特殊去除,通常仅代表两端

    trim:非空判断后,去除前后空格(半角)

    strip(String str, String stripChars):去除(剥夺)字符串某(两)端给定字符(默认为null)

    stripStart / stripEnd

    stripAccents:去"重音",关系不大

    chomp:去除str尾部的换行符,属于截串的特殊方法

    chop:去除最后一个字符+去除str尾部的换行符

    补充:1967年公布的assic码(美国信息互换标准代码)是7位编码,包括95个图形字符+33个控制字符,主要用在电传打字机上,后来成为了计算机 上最重要的标准,由于太偏向M帝,面对那些以英语为主要语言的国家,竟然不太适合,英镑,西欧的重音符都无法表示,好在计算机是以八位存储字符的,故有了 第八位拓展,再然后就有了unicode,而unicode改变了一个字节代表1字符的关系,一本书,一段字符的大小,也不再仅仅由字符的多少决定 了。。。

        public static String trim(String str) {
            return str == null ? null : str.trim();
        }//null安全
        public static String stripStart(String str, String stripChars) {
            int strLen;
            if (str == null || (strLen = str.length()) == 0) {
                return str;
            }
            int start = 0;
            if (stripChars == null) {
                while (start != strLen && Character.isWhitespace(str.charAt(start))) {//null就是去空格
                    start++;
                }
            } else if (stripChars.length() == 0) {
                return str;
            } else {
    //可见去除的是连续存在stripChars中的字符
    while (start != strLen && stripChars.indexOf(str.charAt(start)) != INDEX_NOT_FOUND) { start++; } } return str.substring(start); }
    ...   //chomp
    int lastIdx = str.length() - 1;
            char last = str.charAt(lastIdx);
            if (last == CharUtils.LF) {
                if (str.charAt(lastIdx - 1) == CharUtils.CR) { //
    
                    lastIdx--;
                }
            } else if (last != CharUtils.CR) {
                lastIdx++;
            }
            return str.substring(0, lastIdx);
    ...//chop 
     if (strLen < 2) {
                return EMPTY;
            }
    int lastIdx = strLen - 1;
            String ret = str.substring(0, lastIdx);
            char last = str.charAt(lastIdx);
            if (last == CharUtils.LF && ret.charAt(lastIdx - 1) == CharUtils.CR) {
                return ret.substring(0, lastIdx - 1);
            }
            return ret;

    3.查询:

    indexOf系列,包括indexOfIgnoreCase  lastIndexOf   lastIndexOfIgnoreCase lastIndexOfAny indexOfAnyBut
    ordinalIndexOf :对indexOf的拓展,获取匹配字符串指定次数的索引

    4.截取

    substring(String str, int start, int end):截取字符串,参数为索引

    包括substringBefore   substringAfter  substringBeforeLast  substringAfterLast

    left / right / mid(String str, int pos, int len):参数为len

    //可以发现实现上对于不正确的数据直接抛异常,而调用则通过中间层(工具类)来排除错误
    //,另外,beginIndex为索引,而    endIndex为ex索引(索引+1),或者是算头不算尾
    public static String substring(String str, int start) { if (str == null) { return null; } // handle negatives, which means last n characters if (start < 0) { start = str.length() + start; // remember start is negative } if (start < 0) { start = 0; } if (start > str.length()) { return EMPTY; } return str.substring(start); }
        public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > count) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        if (beginIndex > endIndex) {
            throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
        }
        return ((beginIndex == 0) && (endIndex == count)) ? this :
            new String(offset + beginIndex, endIndex - beginIndex, value);
        }
    //mid left right
    str.substring(str.length() - len);//right str.substring(pos, pos + len);//mid str.substring(0, len);//left
       public static String substringBefore(String str, String separator) {
            if (isEmpty(str) || separator == null) {
                return str;
            }
            if (separator.length() == 0) {
                return EMPTY;
            }
            int pos = str.indexOf(separator);//获取第一个指定字符前所有字符
            if (pos == INDEX_NOT_FOUND) {
                return str;
            }
            return str.substring(0, pos);
        }

    5.分组

    split:匹配任意字符进行分组  (不同于String.split)

    splitByWholeSeparator:匹配全部字符,可以连续匹配

    splitPreserveAllTokens:同上,但不能连续匹配

    splitByCharacterType:根据Character类型进行匹配

    splitByCharacterTypeCamelCase:同上,支持驼峰

    String.split:通过Pattern(正则表达式的编译表示形式)实现

    栗子:

    StringUtils.split("split","pi");//{s,l,t}
    StringUtils.splitByWholeSeparator("1   2  "," ");//{1,2,}
    StringUtils.splitPreserveAllTokens("1   2  "," ");//{1,,,2,,}
    StringUtils.splitByCharacterType("splitByCharacterTypeCamelCase");//{split,B,y,C,haracter,T,ype,C,amel,C,ase}    
    StringUtils.splitByCharacterTypeCamelCase("splitByCharacterTypeCamelCase");//{split,By,Character,Type,Camel,Case}
        

    关键源码:

     ...//split
    if (separatorChars.indexOf(str.charAt(i)) >= 0) {//字符串str.charAt(i),是否存在separatorChars中判断 ...
    ...//splitByWholeSeparator  splitPreserveAllTokens
    while (end < len) { end = str.indexOf(separator, beg);//跟split相反,为全匹配 if (end > -1) { if (end > beg) { numberOfSubstrings += 1; if (numberOfSubstrings == max) { //max为分组限制 end = len; substrings.add(str.substring(beg)); } else { //通常添加 substrings.add(str.substring(beg, end)); beg = end + separatorLength; } } else { if (preserveAllTokens) { //连续匹配处理  numberOfSubstrings += 1;
                            if (numberOfSubstrings == max) {
                                end = len;
                                substrings.add(str.substring(beg));
                            } else {
                                substrings.add(EMPTY);
                            } } beg
    = end + separatorLength; } } else {//最后一组 substrings.add(str.substring(beg)); end = len; } }
    ...//splitByCharacterType    splitByCharacterTypeCamelCase
    int type = Character.getType(c[pos]);//判断类型 ...if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) { int newTokenStart = pos - 1; if (newTokenStart != tokenStart) { list.add(new String(c, tokenStart, newTokenStart - tokenStart)); tokenStart = newTokenStart; } } else { list.add(new String(c, tokenStart, pos - tokenStart)); tokenStart = pos; } currentType = type;

    6. 合并

     join:分组的反操作

    System.out.println(StringUtils.join(new String[]{"j","o","i","n"},"-"));//j-o-i-n
    System.out.println(StringUtils.join(Arrays.asList(null,"j",null,"o","i","n",null),"-"));//-j--o-i-n-
      
    ...  for (int i = startIndex; i < endIndex; i++) {
       if (i > startIndex) {
         buf.append(separator);
          }
       if (array[i] != null) { //null就是 ""
         buf.append(array[i]);
          }
        }
    return buf.toString();

    7.删除:先进行对应查询在截串

    deleteWhitespace :去除各种空格  

    removeStart(removeStartIgnoreCase):当第一段字符为匹配字符时,去除 

    removeEnd(removeEndIgnoreCase):当最后一段字符为匹配字符时,去除

    remove:删除匹配到的全部字符

    System.out.println(StringUtils.deleteWhitespace("A B    c a b    C "));//ABcabC
    System.out.println(StringUtils.removeStart("ABcacbC","a"));//ABcacbC
    System.out.println(StringUtils.removeStartIgnoreCase("ABcacbC","a"));//BcacbC
    System.out.println(StringUtils.removeEnd("ABcacbC","c"));//ABcacbC
    System.out.println(StringUtils.removeEndIgnoreCase("ABcacbC","c"));//ABcacb
    System.out.println(StringUtils.remove("ABcacbC","c"));//ABabC

    8.替换

    replaceOnce:替换第一个合格规定的

    replace:替换所有合格规定的

    replaceEach:参数为数组且一一对应,包含输入参数不等判断

    replaceEachRepeatedly:replaceEach的迭代

    replaceChars:replaceEach的字符版

    overlay(String str, String overlay, int start, int end):所需参数不一样,可以变插入

     System.out.println(StringUtils.replaceOnce("abABab", "a","1"));//1bABab
     System.out.println(StringUtils.replace("abABab", "a","1"));//1bAB1b
     StringUtils.replaceEach("ABB", new String[]{"AB"},new String[]{"A"});//AB
     StringUtils.replaceEachRepeatedly("ABb", new String[]{"AB","b"},new String[]{"A","B"});//A System.out.println(StringUtils.replaceChars("abABab",'a','1'));//1bAB1b System.out.println(StringUtils.replaceChars("abABab ","ab","12"));//12AB12
    System.out.println(StringUtils.overlay("abcdefg","一二三",1,2));//a一二三cdefg
    ...//replaceOnce 与 replace
    while (end != INDEX_NOT_FOUND) {
       buf.append(text.substring(start, end)).append(replacement);
       start = end + replLength;
       if (--max == 0) {    //替换次数,replaceOnce为1,replace为-1
          break;
         end = text.indexOf(searchString, start);
            }
      buf.append(text.substring(start));
    ...

    9.添加

    repeat:循环

    leftPad /rightPad/center :补齐最低字符数 (中文,英文与字符是一比一的关系,但宽度不一样,需要特殊处理)

    System.out.println(StringUtils.rightPad("xx", 5, "阿"));//xx阿阿阿
    System.out.println(StringUtils.rightPad("xx", 5, "a"));//xxaaa
    System.out.println(StringUtils.center ("xx", 5, "a"));//axxaa

     10.转换,多为去null后直接调用String

    upperCase:大写

    lowerCase:小写

    capitalize:首字母大写

    uncapitalize:首字母小写

    swapCase:大小写互转

    reverse:倒叙

    reverseDelimited:先分组,在倒叙

    abbreviate(String str, int offset, int maxWidth):缩写写法,超出长度用...补齐很有用(缺点同补齐)

    abbreviateMiddle(String str, String middle, int length):中间替换

       public static String capitalize(String str) {
            int strLen;
            if (str == null || (strLen = str.length()) == 0) {
                return str;
            }
            return new StringBuilder(strLen)
                .append(Character.toTitleCase(str.charAt(0))) //只有首字母- -
                .append(str.substring(1))
                .toString();
        }
    ...//uncapitalize
     return new StringBuilder(strLen)
                .append(Character.toLowerCase(str.charAt(0))) //转换大小要谨慎,小写随意,当然,与我们无关
                .append(str.substring(1))
                .toString();

    特殊

    --Difference

    difference(String str1, String str2):去除str2中与str1相同的地方

    indexOfDifference(CharSequence cs1, CharSequence cs2):获取两处第一次不同的索引

    indexOfDifference(CharSequence... css):数组版

    getCommonPrefix(String... strs):获取相同字符-->indexOfDifference+截串

    --其他

    int getLevenshteinDistance(CharSequence s, CharSequence t):计算相似度,理论时间到了- -

    LevenshTeinDistance是俄罗斯科学家Vladimir Levenshtein在1965年提出的根据编辑距离(Edit Distance)计算字符串相似度的一种算法。

  • 相关阅读:
    (Java) LeetCode 44. Wildcard Matching —— 通配符匹配
    (Java) LeetCode 30. Substring with Concatenation of All Words —— 与所有单词相关联的字串
    (Java) LeetCode 515. Find Largest Value in Each Tree Row —— 在每个树行中找最大值
    (Java) LeetCode 433. Minimum Genetic Mutation —— 最小基因变化
    (Java) LeetCode 413. Arithmetic Slices —— 等差数列划分
    (Java) LeetCode 289. Game of Life —— 生命游戏
    (Java) LeetCode 337. House Robber III —— 打家劫舍 III
    (Java) LeetCode 213. House Robber II —— 打家劫舍 II
    (Java) LeetCode 198. House Robber —— 打家劫舍
    (Java) LeetCode 152. Maximum Product Subarray —— 乘积最大子序列
  • 原文地址:https://www.cnblogs.com/liuCy/p/3494813.html
Copyright © 2011-2022 走看看