package com.jfai.util;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
/**
* @author wanglf
* @version 1.6.3
* @Package com.jfai.kg.util
* @Description: StringUtil
* @date 2018年7月1日13:54:26
* @remark
* 新增isNull判斷專制各種空值問題 2018年7月13日17:34:45
* 新增獲取隨機年齡,手機號,身份證號等測試數據功能 2018年8月5日09:47:18
* 集成修復unicode轉義字符串功能 2018年8月5日09:56:20
* 新增cumulationOne功能 2018年8月13日17:07:15
* 重構 2018年8月14日18:04:44
* 新增首字母大小寫轉換方法 2018年8月23日16:31:37
*/
@Slf4j
public class StringUtil {
/**
* 百家姓
*/
public static final String XS = "趙錢孫李周吳鄭王馮陳褚衛蔣沈韓楊朱秦尤許何呂施張孔曹嚴華金魏陶姜戚謝鄒喻柏水竇章雲蘇潘葛奚範彭郎魯韋昌馬苗鳳花方俞任袁柳酆鮑史唐費廉岑薛雷賀倪湯滕殷羅畢郝鄔安常樂於時傅皮卞齊康伍餘元卜顧孟平黃和穆蕭尹姚邵湛汪祁毛禹狄米貝明臧計伏成戴談宋茅龐熊紀舒屈項祝董樑杜阮藍閔席季麻強賈路婁危江童顏郭梅盛林刁鍾徐邱駱高夏蔡田樊胡凌霍虞萬支柯昝管盧莫經房裘繆幹解應宗丁宣賁鄧鬱單杭洪包諸左石崔吉鈕龔程嵇邢滑裴陸榮翁荀羊於惠甄曲家封芮羿儲靳汲邴糜鬆井段富巫烏焦巴弓牧隗山谷車侯宓蓬全郗班仰秋仲伊宮寧仇欒暴甘鈄厲戎祖武符劉景詹束龍葉幸司韶郜黎薊薄印宿白懷蒲邰從鄂索鹹籍賴卓藺屠蒙池喬陰鬱胥能蒼雙聞莘黨翟譚貢勞逄姬申扶堵冉宰酈雍卻璩桑桂濮牛壽通邊扈燕冀郟浦尚農溫別莊晏柴瞿閻充慕連茹習宦艾魚容向古易慎戈廖庾終暨居衡步都耿滿弘匡國文寇廣祿闕東歐殳沃利蔚越夔隆師鞏厙聶晁勾敖融冷訾辛闞那簡饒空曾毋沙乜養鞠須豐巢關蒯相查後荊紅遊竺權逯蓋益桓公万俟司馬上官歐陽夏侯諸葛聞人東方赫連皇甫尉遲公羊澹臺公冶宗政濮陽淳于單于太叔申屠公孫仲孫軒轅令狐鍾離宇文長孫慕容鮮于閭丘司徒司空丌官司寇仉督子車顓孫端木巫馬公西漆雕樂正壤駟公良拓跋夾谷宰父穀梁晉楚閆法汝鄢塗欽段幹百里東郭南門呼延歸海羊舌微生嶽帥緱亢況郈有琴樑丘左丘東門西門商牟佘佴伯賞南宮墨哈譙笪年愛陽佟";
public static final String BASE = "abcdefghijklmnopqrstuvwxyz0123456789";
public static final String BASE_MIN = "abcdefghijkmnpqrtuvwxyz0123456789";
public static final String BASE_EX = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static int[] months = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
private static Random random = new Random();
/**
* 獲取簡單的中文名字
*/
public static String getSimpleChineseName() {
StringBuilder sb = new StringBuilder();
sb.append(XS.charAt(new Random().nextInt(XS.length()))).append(getRandomChineseChar()).append(getRandomChineseChar());
return sb.toString();
}
/**
* 獲取隨機年齡,一般用來做測試數據用
*
* @return 隨機年齡
* @Attention: 返回的年齡數字在10-99
*/
public static int getRandomAge() {
return Integer.parseInt(getNum(2));
}
/**
* 獲取隨機生日字符串,返回yyyyMMdd格式的日期字符串
*
* @return 隨機的生日字符串, yyyyMMdd格式
* @Attention:返回的年齡區間在1910-2018年之間,暫不包含2018
* @remark:new Random().nextInt(10) 會返回0-9之間的隨機整數,包括0或9,但不包括10
*/
public static String getRandomBirthdayString() {
int year = 1910 + random.nextInt(108);
int month = months[random.nextInt(12)];
int day = 1 + random.nextInt(28);
StringBuilder stb = new StringBuilder();
stb.append(year);
if (month < 10) {
stb.append("0").append(month);
} else {
stb.append(month);
}
if (day < 10) {
stb.append("0").append(day);
} else {
stb.append(day);
}
return stb.toString();
}
/**
* 獲取隨機身份證號,注意該身份證號只是大致看着相似,用來測試用,嚴格的身份證號校驗是通不過的
*
* @return 隨機的18位身份證號
* @Attention:嚴格的身份證號校驗是通不過的
*/
public static String getRandomIDNo() {
// RegUtil 如不想引用 可以用隨機的兩位數字替代前兩位
Object[] array = RegUtil.GetAreaCode().keySet().toArray();
String areacode = (String) array[random.nextInt(array.length)];
StringBuilder stb = new StringBuilder(areacode);
stb.append(getNum(4)).append(getRandomBirthdayString()).append(getNum(4));
return stb.toString();
}
/**
* 獲取隨機手機號,注意有可能在在嚴格的手機號驗證中通不過
*
* @return 隨機手機號
*/
public static String getRandomMobileNumber() {
StringBuilder stb = new StringBuilder();
stb.append(1).append(3 + random.nextInt(7)).append(getNum(9));
return stb.toString();
}
/**
* 獲取一段指定長度首字母不爲0的隨機數字
*
* @param count 要獲取的隨機數字的位數
* @return 隨機數字組成的字符串
* @Attention 首字母時
*/
public static String getRandomNumber(int count) {
return getNum(count);
}
public static String getRandomStr(int length) {
if (length <= 0) {
return "";
}
int randomNum;
char randomChar;
// StringBuffer類型的可以append增加字符
StringBuffer stb = new StringBuffer();
for (int i = 0; i < length; i++) {
// 可生成[0,n)之間的整數,獲得隨機位置
randomNum = random.nextInt(BASE_MIN.length());
// 獲得隨機位置對應的字符
randomChar = BASE_MIN.charAt(randomNum);
// 組成一個隨機字符串
stb.append(randomChar);
}
return stb.toString();
}
/**
* @return 單個常見漢字字符
* @Description: 隨機生成單個常見漢字
*/
public static String getRandomChineseChar() {
String str = "";
int highCode;
int lowCode;
Random random = new Random();
highCode = (176 + Math.abs(random.nextInt(39))); // B0 + 0~39(16~55) 一級漢字所佔區
lowCode = (161 + Math.abs(random.nextInt(93))); // A1 + 0~93 每區有94個漢字
byte[] b = new byte[2];
b[0] = (Integer.valueOf(highCode)).byteValue();
b[1] = (Integer.valueOf(lowCode)).byteValue();
try {
str = new String(b, "GBK");
} catch (Exception e) {
log.error("Exception :", e);
}
return str;
}
/**
* 獲取一段指定長度首字母不爲0的隨機數字
*
* @param count 要獲取的隨機數字的位數
* @return 隨機數字組成的字符串
*/
public static String getNum(int count) {
if (count <= 0) {
return "";
}
StringBuilder s = new StringBuilder();
for (int i = 0; i < count; i++) {
s.append(new Random().nextInt(10));
}
String string = s.toString();
// 如果第一位數字爲0,則替換爲1
return string.charAt(0) == '0' ? "1" + string.substring(1) : string;
}
/**
* 獲取UUID
*/
public static String getUUID() {
return UUID.randomUUID().toString();
}
/**
* 字符串替換,將 source 中的 oldString 全部換成 newString
*
* @param source 源字符串
* @param oldString 老的字符串
* @param newString 新的字符串
* @return 替換後的字符串
* @Description 主要用於輸入的表單字符串轉化成HTML格式的文本
*/
public static String Replace(String source, String oldString, String newString) {
StringBuffer output = new StringBuffer();
int lengthOfSource = source.length(); // 源字符串長度
int lengthOfOld = oldString.length(); // 老字符串長度
int posStart = 0; // 開始搜索位置
int pos; // 搜索到老字符串的位置
while ((pos = source.indexOf(oldString, posStart)) >= 0) {
output.append(source.substring(posStart, pos));
output.append(newString);
posStart = pos + lengthOfOld;
}
if (posStart < lengthOfSource) {
output.append(source.substring(posStart));
}
return output.toString();
}
/**
* 將傳入的字符串形式的數字,累加1後以字符串的形式返回
*
* @param num
* @return 累加1後的字符串
* @version 1.0.0
* @Attention 傳入的必須是數字
*/
public static String cumulationOne(String num) {
long parseLong = Long.parseLong(num);
return String.valueOf((parseLong + 1));
}
/**
* @param key String
* @param value String
* @return HashMap<String, String>
*/
public static Map <String, String> toMap(String key, String value) {
Map <String, String> map = new LinkedHashMap <String, String>();
map.put(key, value);
return map;
}
/**
* @param key String
* @param value Object
* @return Map<String, Object>
*/
public static Map <String, Object> toMap(String key, Object value) {
Map <String, Object> map = new LinkedHashMap <String, Object>();
map.put(key, value);
return map;
}
/**
* 判斷字符串是否爲int類型數據
*
* @param str
* @return boolean
*/
public static boolean isInt(String str) {
try {
Integer.parseInt(str);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 判斷字符串是否爲long類型數據
*
* @param str
* @return boolean
*/
public static boolean isLong(String str) {
try {
Long.parseLong(str);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 判斷字符是否爲空
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* 判斷字符是否爲不爲空
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 判斷字符是否爲空或空白字符串或null組成
*/
public static boolean isBlank(String str) {
return str == null || str.length() == 0 || str.trim().equals("");
}
/**
* 判斷字符是否爲不爲空或空白字符串組成
*/
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
/**
* 判斷字符是否爲空或空白字符串,或各種null組成
*/
public static boolean isNull(String str) {
return str == null || str.length() == 0 || "".equals(str.trim()) || "NULL".equals(str.trim().toUpperCase());
}
/**
* 判斷字符是否爲不爲空或空白字符串,或各種null組成
*/
public static boolean isNotNull(String str) {
return !isNull(str);
}
/**
* 判斷字符串是否可用 [isNotNull功能的升級版]
*/
public static boolean isAvailable(String str) {
return !(str == null || str.length() == 0 || "".equals(str.trim()) || "NULL".equals(str.trim().toUpperCase()) || "NULLNULL".equals(str.trim().toUpperCase()) || "NULLNULLNULL".equals(str.trim().toUpperCase()));
}
/**
* 覈查字符長度
*/
public static boolean checkLength(String str, int minlen, int maxlen) {
int len = 0;
if (str != null) {
len = str.length();
}
if (len >= minlen && len <= maxlen) {
return true;
} else {
return false;
}
}
/**
* @param str
* @Description: 判斷字符串是否是UUID字符串
*/
public static boolean isUUID(String str) {
try {
UUID.fromString(str);
return true;
} catch (Exception e) {
return false;
}
}
/**
* 首字母轉小寫
*/
public static String toLowerCaseFirstOne(String s) {
if (Character.isLowerCase(s.charAt(0)))
return s;
else
return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
}
/**
* 首字母轉大寫
*/
public static String toUpperCaseFirstOne(String s) {
if (Character.isUpperCase(s.charAt(0)))
return s;
else
return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
}
/**
* 依據start(開始位置)和end(結束位置)截取目標字符串,包含start和end位置
*
* @param start 截取的開始位置 注:是自然位置不是下標
* @param end 結束位置,自然位置不是下標
* @param str 目標字符串
* @return 截取的目標字符串
* @version 1.0.0
* @Attention 參數start和end都是自然位置, 注意自然位置不包括0, 最大長度就是字符串長度..
* start如果小於等於0,會自動調整到開始位置,end如果超出源字符串最大長度,則自動調整爲源字符串結束位置
*/
public static String getStr(int start, int end, String str) {
if (start <= 0) {
start = 1;
}
if (end > str.length()) {
end = str.length();
}
return str.substring(start - 1, end);
}
/**
* 修改字符串中的unicode碼,將unicode編碼轉換成原來的字符
*
* @param s 源str
* @return 修改後的str
*/
private static String decode(String s) {
StringBuilder sb = new StringBuilder(s.length());
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c == '\\' && chars[i + 1] == 'u') {
char cc = 0;
for (int j = 0; j < 4; j++) {
char ch = Character.toLowerCase(chars[i + 2 + j]);
if ('0' <= ch && ch <= '9' || 'a' <= ch && ch <= 'f') {
cc |= (Character.digit(ch, 16) << (3 - j) * 4);
} else {
cc = 0;
break;
}
}
if (cc > 0) {
i += 5;
sb.append(cc);
continue;
}
}
sb.append(c);
}
return sb.toString();
}
/**
* 獲取修復unicode轉義後的字符串 如 將字符串中的 "\u003d" 轉回其原本的值
*
* @param str
* @return 修復後的字符串
*/
public static String getFixStrBecauseUnicodeEscape(String str) {
Pattern p = Pattern.compile("(\\\\u.{4})");
Matcher m = p.matcher(str);
while (m.find()) {
String xxx = m.group();
str = str.replaceAll("\\" + xxx, decode(xxx));
}
return str;
}
}