StringUtil.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. package com.simuwang.base.common.util;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import java.util.List;
  5. import cn.hutool.core.text.StrFormatter;
  6. import com.simuwang.base.common.conts.Constants;
  7. import org.apache.commons.lang3.StringUtils;
  8. import org.springframework.util.AntPathMatcher;
  9. import java.util.*;
  10. public class StringUtil {
  11. /** 空字符串 */
  12. private static final String NULLSTR = "";
  13. private static final int STRING_BUILDER_SIZE = 256;
  14. public static final String SPACE = " ";
  15. public static final String EMPTY = "";
  16. public static final String LF = "\n";
  17. public static final String CR = "\r";
  18. /** 下划线 */
  19. private static final char SEPARATOR = '_';
  20. public static String retainChineseCharacters(String value, List<String> notConvertFieldList) {
  21. if (StrUtil.isBlank(value)) {
  22. return null;
  23. }
  24. if (CollUtil.isNotEmpty(notConvertFieldList) && notConvertFieldList.contains(value)) {
  25. return value;
  26. }
  27. // 正则表达式匹配中文字符
  28. String regex = "[^\\u4e00-\\u9fa5]";
  29. // 使用空字符串替换所有非中文字符
  30. return value.replaceAll(regex, "");
  31. }
  32. public static boolean isNumeric(String value) {
  33. if (StrUtil.isBlank(value)) {
  34. return false;
  35. }
  36. return value.matches("^[-+]?[0-9]*\\.?[0-9]+$");
  37. }
  38. /**
  39. * 获取参数不为空值
  40. *
  41. * @param value defaultValue 要判断的value
  42. * @return value 返回值
  43. */
  44. public static <T> T nvl(T value, T defaultValue)
  45. {
  46. return value != null ? value : defaultValue;
  47. }
  48. /**
  49. * * 判断一个Collection是否为空, 包含List,Set,Queue
  50. *
  51. * @param coll 要判断的Collection
  52. * @return true:为空 false:非空
  53. */
  54. public static boolean isEmpty(Collection<?> coll)
  55. {
  56. return isNull(coll) || coll.isEmpty();
  57. }
  58. /**
  59. * * 判断一个Collection是否非空,包含List,Set,Queue
  60. *
  61. * @param coll 要判断的Collection
  62. * @return true:非空 false:空
  63. */
  64. public static boolean isNotEmpty(Collection<?> coll)
  65. {
  66. return !isEmpty(coll);
  67. }
  68. /**
  69. * * 判断一个对象数组是否为空
  70. *
  71. * @param objects 要判断的对象数组
  72. ** @return true:为空 false:非空
  73. */
  74. public static boolean isEmpty(Object[] objects)
  75. {
  76. return isNull(objects) || (objects.length == 0);
  77. }
  78. /**
  79. * * 判断一个对象数组是否非空
  80. *
  81. * @param objects 要判断的对象数组
  82. * @return true:非空 false:空
  83. */
  84. public static boolean isNotEmpty(Object[] objects)
  85. {
  86. return !isEmpty(objects);
  87. }
  88. /**
  89. * * 判断一个Map是否为空
  90. *
  91. * @param map 要判断的Map
  92. * @return true:为空 false:非空
  93. */
  94. public static boolean isEmpty(Map<?, ?> map)
  95. {
  96. return isNull(map) || map.isEmpty();
  97. }
  98. /**
  99. * * 判断一个Map是否为空
  100. *
  101. * @param map 要判断的Map
  102. * @return true:非空 false:空
  103. */
  104. public static boolean isNotEmpty(Map<?, ?> map)
  105. {
  106. return !isEmpty(map);
  107. }
  108. /**
  109. * * 判断一个字符串是否为空串
  110. *
  111. * @param str String
  112. * @return true:为空 false:非空
  113. */
  114. public static boolean isEmpty(String str)
  115. {
  116. return isNull(str) || NULLSTR.equals(str.trim());
  117. }
  118. /**
  119. * * 判断一个字符串是否为非空串
  120. *
  121. * @param str String
  122. * @return true:非空串 false:空串
  123. */
  124. public static boolean isNotEmpty(String str)
  125. {
  126. return !isEmpty(str);
  127. }
  128. /**
  129. * * 判断一个对象是否为空
  130. *
  131. * @param object Object
  132. * @return true:为空 false:非空
  133. */
  134. public static boolean isNull(Object object)
  135. {
  136. return object == null;
  137. }
  138. /**
  139. * * 判断一个对象是否非空
  140. *
  141. * @param object Object
  142. * @return true:非空 false:空
  143. */
  144. public static boolean isNotNull(Object object)
  145. {
  146. return !isNull(object);
  147. }
  148. /**
  149. * * 判断一个对象是否是数组类型(Java基本型别的数组)
  150. *
  151. * @param object 对象
  152. * @return true:是数组 false:不是数组
  153. */
  154. public static boolean isArray(Object object)
  155. {
  156. return isNotNull(object) && object.getClass().isArray();
  157. }
  158. /**
  159. * 去空格
  160. */
  161. public static String trim(String str)
  162. {
  163. return (str == null ? "" : str.trim());
  164. }
  165. /**
  166. * 截取字符串
  167. *
  168. * @param str 字符串
  169. * @param start 开始
  170. * @return 结果
  171. */
  172. public static String substring(final String str, int start)
  173. {
  174. if (str == null)
  175. {
  176. return NULLSTR;
  177. }
  178. if (start < 0)
  179. {
  180. start = str.length() + start;
  181. }
  182. if (start < 0)
  183. {
  184. start = 0;
  185. }
  186. if (start > str.length())
  187. {
  188. return NULLSTR;
  189. }
  190. return str.substring(start);
  191. }
  192. /**
  193. * 截取字符串
  194. *
  195. * @param str 字符串
  196. * @param start 开始
  197. * @param end 结束
  198. * @return 结果
  199. */
  200. public static String substring(final String str, int start, int end)
  201. {
  202. if (str == null)
  203. {
  204. return NULLSTR;
  205. }
  206. if (end < 0)
  207. {
  208. end = str.length() + end;
  209. }
  210. if (start < 0)
  211. {
  212. start = str.length() + start;
  213. }
  214. if (end > str.length())
  215. {
  216. end = str.length();
  217. }
  218. if (start > end)
  219. {
  220. return NULLSTR;
  221. }
  222. if (start < 0)
  223. {
  224. start = 0;
  225. }
  226. if (end < 0)
  227. {
  228. end = 0;
  229. }
  230. return str.substring(start, end);
  231. }
  232. /**
  233. * 判断是否为空,并且不是空白字符
  234. *
  235. * @param str 要判断的value
  236. * @return 结果
  237. */
  238. public static boolean hasText(String str)
  239. {
  240. return (str != null && !str.isEmpty() && containsText(str));
  241. }
  242. private static boolean containsText(CharSequence str)
  243. {
  244. int strLen = str.length();
  245. for (int i = 0; i < strLen; i++)
  246. {
  247. if (!Character.isWhitespace(str.charAt(i)))
  248. {
  249. return true;
  250. }
  251. }
  252. return false;
  253. }
  254. /**
  255. * 格式化文本, {} 表示占位符<br>
  256. * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
  257. * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
  258. * 例:<br>
  259. * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
  260. * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
  261. * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
  262. *
  263. * @param template 文本模板,被替换的部分用 {} 表示
  264. * @param params 参数值
  265. * @return 格式化后的文本
  266. */
  267. public static String format(String template, Object... params)
  268. {
  269. if (isEmpty(params) || isEmpty(template))
  270. {
  271. return template;
  272. }
  273. return StrFormatter.format(template, params);
  274. }
  275. /**
  276. * 是否为http(s)://开头
  277. *
  278. * @param link 链接
  279. * @return 结果
  280. */
  281. public static boolean ishttp(String link)
  282. {
  283. return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
  284. }
  285. /**
  286. * 字符串转set
  287. *
  288. * @param str 字符串
  289. * @param sep 分隔符
  290. * @return set集合
  291. */
  292. public static final Set<String> str2Set(String str, String sep)
  293. {
  294. return new HashSet<String>(str2List(str, sep, true, false));
  295. }
  296. /**
  297. * 字符串转list
  298. *
  299. * @param str 字符串
  300. * @param sep 分隔符
  301. * @param filterBlank 过滤纯空白
  302. * @param trim 去掉首尾空白
  303. * @return list集合
  304. */
  305. public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
  306. {
  307. List<String> list = new ArrayList<String>();
  308. if (StringUtils.isEmpty(str))
  309. {
  310. return list;
  311. }
  312. // 过滤空白字符串
  313. if (filterBlank && StringUtils.isBlank(str))
  314. {
  315. return list;
  316. }
  317. String[] split = str.split(sep);
  318. for (String string : split)
  319. {
  320. if (filterBlank && StringUtils.isBlank(string))
  321. {
  322. continue;
  323. }
  324. if (trim)
  325. {
  326. string = string.trim();
  327. }
  328. list.add(string);
  329. }
  330. return list;
  331. }
  332. /**
  333. * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
  334. *
  335. * @param collection 给定的集合
  336. * @param array 给定的数组
  337. * @return boolean 结果
  338. */
  339. public static boolean containsAny(Collection<String> collection, String... array)
  340. {
  341. if (isEmpty(collection) || isEmpty(array))
  342. {
  343. return false;
  344. }
  345. else
  346. {
  347. for (String str : array)
  348. {
  349. if (collection.contains(str))
  350. {
  351. return true;
  352. }
  353. }
  354. return false;
  355. }
  356. }
  357. /**
  358. * 驼峰转下划线命名
  359. */
  360. public static String toUnderScoreCase(String str)
  361. {
  362. if (str == null)
  363. {
  364. return null;
  365. }
  366. StringBuilder sb = new StringBuilder();
  367. // 前置字符是否大写
  368. boolean preCharIsUpperCase = true;
  369. // 当前字符是否大写
  370. boolean curreCharIsUpperCase = true;
  371. // 下一字符是否大写
  372. boolean nexteCharIsUpperCase = true;
  373. for (int i = 0; i < str.length(); i++)
  374. {
  375. char c = str.charAt(i);
  376. if (i > 0)
  377. {
  378. preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
  379. }
  380. else
  381. {
  382. preCharIsUpperCase = false;
  383. }
  384. curreCharIsUpperCase = Character.isUpperCase(c);
  385. if (i < (str.length() - 1))
  386. {
  387. nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
  388. }
  389. if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
  390. {
  391. sb.append(SEPARATOR);
  392. }
  393. else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
  394. {
  395. sb.append(SEPARATOR);
  396. }
  397. sb.append(Character.toLowerCase(c));
  398. }
  399. return sb.toString();
  400. }
  401. /**
  402. * 是否包含字符串
  403. *
  404. * @param str 验证字符串
  405. * @param strs 字符串组
  406. * @return 包含返回true
  407. */
  408. public static boolean inStringIgnoreCase(String str, String... strs)
  409. {
  410. if (str != null && strs != null)
  411. {
  412. for (String s : strs)
  413. {
  414. if (str.equalsIgnoreCase(trim(s)))
  415. {
  416. return true;
  417. }
  418. }
  419. }
  420. return false;
  421. }
  422. /**
  423. * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
  424. *
  425. * @param name 转换前的下划线大写方式命名的字符串
  426. * @return 转换后的驼峰式命名的字符串
  427. */
  428. public static String convertToCamelCase(String name)
  429. {
  430. StringBuilder result = new StringBuilder();
  431. // 快速检查
  432. if (name == null || name.isEmpty())
  433. {
  434. // 没必要转换
  435. return "";
  436. }
  437. else if (!name.contains("_"))
  438. {
  439. // 不含下划线,仅将首字母大写
  440. return name.substring(0, 1).toUpperCase() + name.substring(1);
  441. }
  442. // 用下划线将原始字符串分割
  443. String[] camels = name.split("_");
  444. for (String camel : camels)
  445. {
  446. // 跳过原始字符串中开头、结尾的下换线或双重下划线
  447. if (camel.isEmpty())
  448. {
  449. continue;
  450. }
  451. // 首字母大写
  452. result.append(camel.substring(0, 1).toUpperCase());
  453. result.append(camel.substring(1).toLowerCase());
  454. }
  455. return result.toString();
  456. }
  457. /**
  458. * 驼峰式命名法
  459. * 例如:user_name->userName
  460. */
  461. public static String toCamelCase(String s)
  462. {
  463. if (s == null)
  464. {
  465. return null;
  466. }
  467. if (s.indexOf(SEPARATOR) == -1)
  468. {
  469. return s;
  470. }
  471. s = s.toLowerCase();
  472. StringBuilder sb = new StringBuilder(s.length());
  473. boolean upperCase = false;
  474. for (int i = 0; i < s.length(); i++)
  475. {
  476. char c = s.charAt(i);
  477. if (c == SEPARATOR)
  478. {
  479. upperCase = true;
  480. }
  481. else if (upperCase)
  482. {
  483. sb.append(Character.toUpperCase(c));
  484. upperCase = false;
  485. }
  486. else
  487. {
  488. sb.append(c);
  489. }
  490. }
  491. return sb.toString();
  492. }
  493. /**
  494. * 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
  495. *
  496. * @param str 指定字符串
  497. * @param strs 需要检查的字符串数组
  498. * @return 是否匹配
  499. */
  500. public static boolean matches(String str, List<String> strs)
  501. {
  502. if (isEmpty(str) || isEmpty(strs))
  503. {
  504. return false;
  505. }
  506. for (String pattern : strs)
  507. {
  508. if (isMatch(pattern, str))
  509. {
  510. return true;
  511. }
  512. }
  513. return false;
  514. }
  515. /**
  516. * 判断url是否与规则配置:
  517. * ? 表示单个字符;
  518. * * 表示一层路径内的任意字符串,不可跨层级;
  519. * ** 表示任意层路径;
  520. *
  521. * @param pattern 匹配规则
  522. * @param url 需要匹配的url
  523. * @return
  524. */
  525. public static boolean isMatch(String pattern, String url)
  526. {
  527. AntPathMatcher matcher = new AntPathMatcher();
  528. return matcher.match(pattern, url);
  529. }
  530. @SuppressWarnings("unchecked")
  531. public static <T> T cast(Object obj)
  532. {
  533. return (T) obj;
  534. }
  535. /**
  536. * 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
  537. *
  538. * @param num 数字对象
  539. * @param size 字符串指定长度
  540. * @return 返回数字的字符串格式,该字符串为指定长度。
  541. */
  542. public static final String padl(final Number num, final int size)
  543. {
  544. return padl(num.toString(), size, '0');
  545. }
  546. /**
  547. * 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
  548. *
  549. * @param s 原始字符串
  550. * @param size 字符串指定长度
  551. * @param c 用于补齐的字符
  552. * @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
  553. */
  554. public static final String padl(final String s, final int size, final char c)
  555. {
  556. final StringBuilder sb = new StringBuilder(size);
  557. if (s != null)
  558. {
  559. final int len = s.length();
  560. if (s.length() <= size)
  561. {
  562. for (int i = size - len; i > 0; i--)
  563. {
  564. sb.append(c);
  565. }
  566. sb.append(s);
  567. }
  568. else
  569. {
  570. return s.substring(len - size, len);
  571. }
  572. }
  573. else
  574. {
  575. for (int i = size; i > 0; i--)
  576. {
  577. sb.append(c);
  578. }
  579. }
  580. return sb.toString();
  581. }
  582. public static boolean equals(CharSequence cs1, CharSequence cs2) {
  583. if (cs1 == cs2) {
  584. return true;
  585. } else if (cs1 != null && cs2 != null) {
  586. if (cs1.length() != cs2.length()) {
  587. return false;
  588. } else if (cs1 instanceof String && cs2 instanceof String) {
  589. return cs1.equals(cs2);
  590. } else {
  591. int length = cs1.length();
  592. for(int i = 0; i < length; ++i) {
  593. if (cs1.charAt(i) != cs2.charAt(i)) {
  594. return false;
  595. }
  596. }
  597. return true;
  598. }
  599. } else {
  600. return false;
  601. }
  602. }
  603. public static boolean compare2NumericValue(String value) {
  604. int parsedInt = Integer.parseInt(value);
  605. // 52962==2044-12-31
  606. return parsedInt <= 52962;
  607. }
  608. }