敏捷工具
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

506 lines
14 KiB

2 years ago
  1. package com.whn.hellospring.utils
  2. import java.io.UnsupportedEncodingException
  3. import java.text.DecimalFormat
  4. import java.text.ParseException
  5. import java.text.SimpleDateFormat
  6. import java.util.Date
  7. import java.util.regex.Pattern
  8. import java.util.regex.PatternSyntaxException
  9. /**
  10. * 字符串操作类
  11. */
  12. object StringUtil {
  13. /**
  14. * 处理重叠字符
  15. * ABCCCD -> AB3CD
  16. */
  17. fun overlapCharacter(list: List<String>): String {
  18. //排序
  19. // java.util.Collections.sort(list)
  20. var j = 0
  21. var finalStr = ""
  22. while (j < list.size) {
  23. val str = list[j] //C
  24. //如果已经存在当前要添加的字符 ABC + C AB2C +C
  25. if (finalStr.contains(str)) {
  26. if (j - 1 < 0) { //第一位 C+C
  27. finalStr = "2" + finalStr
  28. } else {
  29. val index = finalStr.indexOf(str)
  30. if (index > 0) {
  31. val timesStr = finalStr.substring(index - 1, index) //倍数2
  32. if (isInteger(timesStr)) {// AB2C +C
  33. val timesInt = timesStr.toInt() + 1
  34. finalStr = finalStr.substring(0, finalStr.length - 2)
  35. finalStr += timesInt.toString()
  36. finalStr += str
  37. } else {// ABC + C
  38. finalStr = finalStr.substring(0, finalStr.length - 1)
  39. finalStr += "2"
  40. finalStr += str
  41. }
  42. } else { //B2C4D + B
  43. finalStr = "2" + finalStr
  44. }
  45. }
  46. } else {
  47. finalStr += str
  48. }
  49. j++
  50. }
  51. return finalStr
  52. }
  53. /*方法二:推荐,速度最快
  54. * 判断是否为整数
  55. * @param str 传入的字符串
  56. * @return 是整数返回true,否则返回false
  57. */
  58. fun isInteger(str: String): Boolean {
  59. val pattern = Pattern.compile("^[-\\+]?[\\d]*$")
  60. return pattern.matcher(str).matches()
  61. }
  62. /**
  63. * 保留一位小数,四舍五入
  64. * 使用0.00不足位补0,#.##仅保留有效位
  65. */
  66. fun doubleToString1(num: Double?): String {
  67. // if(!isNumber(num.toString()))return "0.0"
  68. // return DecimalFormat("0.0").format(num)
  69. if(!isNumber(num.toString()))return "0.0"
  70. return String.format("%.1f", num!!.toDouble())
  71. }
  72. /**
  73. * 保留两位小数,四舍五入
  74. * 使用0.00不足位补0,#.##仅保留有效位
  75. */
  76. fun doubleToString2(num: Double?): String {
  77. // if(!isNumber(num.toString()))return "0.00"
  78. // return DecimalFormat("0.00").format(num)
  79. if(!isNumber(num.toString()))return "0.00"
  80. return String.format("%.2f", num!!.toDouble())
  81. }
  82. /**
  83. * 四舍五入
  84. * 1位小数
  85. */
  86. fun rounding1(num: String?): String {
  87. if(!isNumber(num))return "0.0"
  88. return String.format("%.1f", num!!.toDouble())
  89. }
  90. /**
  91. * 四舍五入
  92. * 2位小数
  93. */
  94. fun rounding2(num: String?): String {
  95. if(!isNumber(num))return "0.00"
  96. return String.format("%.2f", num!!.toDouble())
  97. }
  98. /**
  99. * 按长度截取中英文混合string
  100. *
  101. * @param text 字符串
  102. * @param length 长度
  103. * @param endWith 末尾追加
  104. * @return
  105. */
  106. fun subStringIncludeChinese(text: String, length: Int,
  107. endWith: String): String {
  108. var text = text
  109. text = text.trim { it <= ' ' }
  110. val textLength = text.length
  111. var byteLength = 0
  112. val returnStr = StringBuffer()
  113. var i = 0
  114. while (i < textLength && byteLength < length * 2) {
  115. val str_i = text.substring(i, i + 1)
  116. if (str_i.toByteArray().size == 1) {// 英文
  117. byteLength++
  118. } else {// 中文
  119. byteLength += 2
  120. }
  121. returnStr.append(str_i)
  122. i++
  123. }
  124. try {
  125. if (byteLength < text.toByteArray(charset("GBK")).size) {// getBytes("GBK")每个汉字长2,getBytes("UTF-8")每个汉字长度为3
  126. returnStr.append(endWith)
  127. }
  128. } catch (e: UnsupportedEncodingException) {
  129. e.printStackTrace()
  130. }
  131. return returnStr.toString()
  132. }
  133. /**
  134. * 获取字符串的长度,如果有中文,则每个中文字符计为2位
  135. *
  136. * @param text 指定的字符串
  137. * @return 字符串的长度
  138. */
  139. fun getStringLengthIncludeChinese(text: String): Int {
  140. var text = text
  141. text = text.trim { it <= ' ' }
  142. var valueLength = 0
  143. val chinese = "[\u0391-\uFFE5]"
  144. /* 获取字段值的长度,如果含中文字符,则每个中文字符长度为2,否则为1 */
  145. for (i in 0..text.length - 1) {
  146. /* 获取一个字符 */
  147. val temp = text.substring(i, i + 1)
  148. /* 判断是否为中文字符 */
  149. if (temp.matches(chinese.toRegex())) {
  150. /* 中文字符长度为2 */
  151. valueLength += 2
  152. } else {
  153. /* 其他字符长度为1 */
  154. valueLength += 1
  155. }
  156. }
  157. return valueLength
  158. }
  159. /**
  160. * 验证邮箱地址是否正确
  161. *
  162. * @param email
  163. * @return
  164. */
  165. fun checkEmail(email: String): Boolean {
  166. var flag = false
  167. try {
  168. val check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"
  169. val regex = Pattern.compile(check)
  170. val matcher = regex.matcher(email)
  171. flag = matcher.matches()
  172. } catch (e: Exception) {
  173. e.printStackTrace()
  174. flag = false
  175. }
  176. return flag
  177. }
  178. /**
  179. * 判断字符串是否是数字
  180. *
  181. * @param number
  182. * @return
  183. */
  184. fun isNumber(number: String?): Boolean {
  185. //如果为空,false
  186. if (!isNotNull(number)) {
  187. return false
  188. }
  189. //只有.
  190. if (number == ".") {
  191. return false
  192. }
  193. //如果有多个点,false
  194. val list = number!!.split(".")
  195. if (list.size > 2) {
  196. return false
  197. }
  198. //如果有其他字符 false
  199. var flag = false
  200. try {
  201. val p = Pattern.compile("[0-9.-]+")
  202. val m = p.matcher(number)
  203. flag = m.matches()
  204. } catch (e: Exception) {
  205. e.printStackTrace()
  206. flag = false
  207. }
  208. return flag
  209. }
  210. /**
  211. * 判断是否全是英文字母组成(不区分大小写)
  212. *
  213. * @param letters
  214. * @return
  215. */
  216. fun isLetters(letters: String): Boolean {
  217. var flag = false
  218. try {
  219. val p = Pattern.compile("^[A-Za-z]+$")
  220. val m = p.matcher(letters)
  221. flag = m.matches()
  222. } catch (e: Exception) {
  223. e.printStackTrace()
  224. flag = false
  225. }
  226. return flag
  227. }
  228. /**
  229. * 判断是否全是大写字母
  230. *
  231. * @param letters
  232. * @return
  233. */
  234. fun isUppercaseLetters(letters: String): Boolean {
  235. var flag = false
  236. try {
  237. val p = Pattern.compile("^[A-Z]+$")
  238. val m = p.matcher(letters)
  239. flag = m.matches()
  240. } catch (e: Exception) {
  241. e.printStackTrace()
  242. flag = false
  243. }
  244. return flag
  245. }
  246. /**
  247. * 判断是否全是小写字母
  248. *
  249. * @param letters
  250. * @return
  251. */
  252. fun isLowercaseLetters(letters: String): Boolean {
  253. var flag = false
  254. try {
  255. val p = Pattern.compile("^[a-z]+$")
  256. val m = p.matcher(letters)
  257. flag = m.matches()
  258. } catch (e: Exception) {
  259. e.printStackTrace()
  260. flag = false
  261. }
  262. return flag
  263. }
  264. /**
  265. * 是否数字和字母组成
  266. *
  267. * @param text
  268. * @return
  269. */
  270. fun isNumbersAndLetters(text: String): Boolean {
  271. var flag = false
  272. try {
  273. val p = Pattern.compile("^[A-Za-z0-9]+$")
  274. val m = p.matcher(text)
  275. flag = m.matches()
  276. } catch (e: Exception) {
  277. e.printStackTrace()
  278. flag = false
  279. }
  280. return flag
  281. }
  282. /**
  283. * 包含数字,字母,下划线,不可以下划线开头
  284. *
  285. * @param text
  286. * @return
  287. */
  288. fun isNumbersUnderlineLetters(text: String): Boolean {
  289. var flag = false
  290. try {
  291. val p = Pattern.compile("^(?!_)(?!.*?_$)[a-zA-Z0-9_]+$")
  292. val m = p.matcher(text)
  293. flag = m.matches()
  294. } catch (e: Exception) {
  295. e.printStackTrace()
  296. flag = false
  297. }
  298. return flag
  299. }
  300. /**
  301. * 是否是密码,(字母或数字开头,包含下划线)
  302. *
  303. * @param text
  304. * @param lowest_median 最低位数
  305. * @param highest_median 最高位数
  306. * @return
  307. */
  308. fun isPassword(text: String, lowest_median: Int,
  309. highest_median: Int): Boolean {
  310. var flag = false
  311. try {
  312. val p = Pattern
  313. .compile("^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{"
  314. + lowest_median.toString() + ","
  315. + highest_median.toString() + "}$")
  316. val m = p.matcher(text)
  317. flag = m.matches()
  318. } catch (e: Exception) {
  319. e.printStackTrace()
  320. flag = false
  321. }
  322. return flag
  323. }
  324. // 过滤特殊字符
  325. @Throws(PatternSyntaxException::class)
  326. fun StringFilter(str: String): String {
  327. // 只允许字母和数字
  328. // String regEx = "[^a-zA-Z0-9]";
  329. // 清除掉所有特殊字符
  330. val regEx = "[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"
  331. val p = Pattern.compile(regEx)
  332. val m = p.matcher(str)
  333. return m.replaceAll("").trim { it <= ' ' }
  334. }
  335. // 中文识别
  336. fun hasChinese(source: String): Boolean {
  337. val reg_charset = "([\\u4E00-\\u9FA5]*+)"
  338. val p = Pattern.compile(reg_charset)
  339. val m = p.matcher(source)
  340. var hasChinese = false
  341. while (m.find()) {
  342. if ("" != m.group(1)) {
  343. hasChinese = true
  344. }
  345. }
  346. return hasChinese
  347. }
  348. /**
  349. * 判断是否有特殊字符
  350. */
  351. fun hasString(str: String): Boolean {
  352. val regEx = "[`~!@#$%^&*()+=|{}':;',//[//].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"// 特殊字符
  353. val p = Pattern.compile(regEx)
  354. val m = p.matcher(str)
  355. return m.find()
  356. }
  357. //获取当前时间
  358. fun refFormatNowDate(): String {
  359. val nowTime = Date(System.currentTimeMillis())
  360. val sdFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  361. return sdFormatter.format(nowTime)
  362. }
  363. //时间格式
  364. fun Realtime(time: String): String {
  365. val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
  366. var str = ""
  367. try {
  368. val curDate = formatter.parse(time)
  369. str = formatter.format(curDate)
  370. } catch (e: ParseException) {
  371. e.printStackTrace()
  372. }
  373. //获取当前时间
  374. return str
  375. }
  376. /**
  377. * 转换文件大小
  378. *
  379. * @param fileS
  380. * @return
  381. */
  382. fun FormetFileSize(fileS: Long): String {
  383. val df = DecimalFormat("#.00")
  384. var fileSizeString = ""
  385. val wrongSize = "0B"
  386. if (fileS == 0L) {
  387. return wrongSize
  388. }
  389. if (fileS < 1024) {
  390. fileSizeString = df.format(fileS.toDouble()) + "B"
  391. } else if (fileS < 1048576) {
  392. fileSizeString = df.format(fileS.toDouble() / 1024) + "KB"
  393. } else if (fileS < 1073741824) {
  394. fileSizeString = df.format(fileS.toDouble() / 1048576) + "MB"
  395. } else {
  396. fileSizeString = df.format(fileS.toDouble() / 1073741824) + "GB"
  397. }
  398. return fileSizeString
  399. }
  400. /**
  401. * 检验数字的有效性
  402. *
  403. * @param str
  404. * @return
  405. */
  406. fun isNumberTrue(str: String): Boolean {
  407. val c = str.substring(str.length - 1, str.length)
  408. if (c == ".") {
  409. return false
  410. }
  411. val pattern = Pattern.compile("^[0-9]+(.[0-9]*)?$")
  412. val match = pattern.matcher(str)
  413. return match.matches()
  414. }
  415. /**
  416. * 大陆号码或香港号码均可
  417. */
  418. @Throws(PatternSyntaxException::class)
  419. fun isPhoneLegal(str: String): Boolean {
  420. return isChinaPhoneLegal(str) || isHKPhoneLegal(str)
  421. }
  422. /**
  423. * 大陆手机号码11位数,匹配格式:前三位固定格式+后8位任意数
  424. * 此方法中前三位格式有:
  425. * 13+任意数
  426. * 15+除4的任意数
  427. * 18+除1和4的任意数
  428. * 17+除9的任意数
  429. * 147
  430. */
  431. @Throws(PatternSyntaxException::class)
  432. fun isChinaPhoneLegal(str: String): Boolean {
  433. // String regExp = "^((13[0-9])|(15[^4])|(18[0-9])|(17[0-9])|(16[0-9])|(147))\\d{8}$";
  434. val regExp = "^\\d{11}$"
  435. val p = Pattern.compile(regExp)
  436. val m = p.matcher(str)
  437. return m.matches()
  438. }
  439. /**
  440. * 香港手机号码8位数,5|6|8|9开头+7位任意数
  441. */
  442. @Throws(PatternSyntaxException::class)
  443. fun isHKPhoneLegal(str: String): Boolean {
  444. val regExp = "^(5|6|8|9)\\d{7}$"
  445. val p = Pattern.compile(regExp)
  446. val m = p.matcher(str)
  447. return m.matches()
  448. }
  449. }