Encrypted messaging app
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.

463 lines
12 KiB

  1. import 'dart:convert';
  2. import 'dart:math';
  3. ///
  4. /// Helper class for String operations
  5. ///
  6. class StringUtils {
  7. static AsciiCodec asciiCodec = AsciiCodec();
  8. ///
  9. /// Returns the given string or the default string if the given string is null
  10. ///
  11. static String defaultString(String? str, {String defaultStr = ''}) {
  12. return str ?? defaultStr;
  13. }
  14. ///
  15. /// Checks if the given String [s] is null or empty
  16. ///
  17. static bool isNullOrEmpty(String? s) =>
  18. (s == null || s.isEmpty) ? true : false;
  19. ///
  20. /// Checks if the given String [s] is not null or empty
  21. ///
  22. static bool isNotNullOrEmpty(String? s) => !isNullOrEmpty(s);
  23. ///
  24. /// Transfers the given String [s] from camcelCase to upperCaseUnderscore
  25. /// Example : helloWorld => HELLO_WORLD
  26. ///
  27. static String camelCaseToUpperUnderscore(String s) {
  28. var sb = StringBuffer();
  29. var first = true;
  30. s.runes.forEach((int rune) {
  31. var char = String.fromCharCode(rune);
  32. if (isUpperCase(char) && !first) {
  33. sb.write('_');
  34. sb.write(char.toUpperCase());
  35. } else {
  36. first = false;
  37. sb.write(char.toUpperCase());
  38. }
  39. });
  40. return sb.toString();
  41. }
  42. ///
  43. /// Transfers the given String [s] from camcelCase to lowerCaseUnderscore
  44. /// Example : helloWorld => hello_world
  45. ///
  46. static String camelCaseToLowerUnderscore(String s) {
  47. var sb = StringBuffer();
  48. var first = true;
  49. s.runes.forEach((int rune) {
  50. var char = String.fromCharCode(rune);
  51. if (isUpperCase(char) && !first) {
  52. if (char != '_') {
  53. sb.write('_');
  54. }
  55. sb.write(char.toLowerCase());
  56. } else {
  57. first = false;
  58. sb.write(char.toLowerCase());
  59. }
  60. });
  61. return sb.toString();
  62. }
  63. ///
  64. /// Checks if the given string [s] is lower case
  65. ///
  66. static bool isLowerCase(String s) {
  67. return s == s.toLowerCase();
  68. }
  69. ///
  70. /// Checks if the given string [s] is upper case
  71. ///
  72. static bool isUpperCase(String s) {
  73. return s == s.toUpperCase();
  74. }
  75. ///
  76. /// Checks if the given string [s] contains only ascii chars
  77. ///
  78. static bool isAscii(String s) {
  79. try {
  80. asciiCodec.decode(s.codeUnits);
  81. } catch (e) {
  82. return false;
  83. }
  84. return true;
  85. }
  86. ///
  87. /// Capitalize the given string [s]. If [allWords] is set to true, it will capitalize all words within the given string [s].
  88. ///
  89. /// The string [s] is there fore splitted by " " (space).
  90. ///
  91. /// Example :
  92. ///
  93. /// * [s] = "world" => World
  94. /// * [s] = "WORLD" => World
  95. /// * [s] = "the quick lazy fox" => The quick lazy fox
  96. /// * [s] = "the quick lazy fox" and [allWords] = true => The Quick Lazy Fox
  97. ///
  98. static String capitalize(String s, {bool allWords = false}) {
  99. if (s.isEmpty) {
  100. return '';
  101. }
  102. s = s.trim();
  103. if (allWords) {
  104. var words = s.split(' ');
  105. var capitalized = [];
  106. for (var w in words) {
  107. capitalized.add(capitalize(w));
  108. }
  109. return capitalized.join(' ');
  110. } else {
  111. return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
  112. }
  113. }
  114. ///
  115. /// Reverse the given string [s]
  116. /// Example : hello => olleh
  117. ///
  118. static String reverse(String s) {
  119. return String.fromCharCodes(s.runes.toList().reversed);
  120. }
  121. ///
  122. /// Counts how offen the given [char] apears in the given string [s].
  123. /// The value [caseSensitive] controlls whether it should only look for the given [char]
  124. /// or also the equivalent lower/upper case version.
  125. /// Example: Hello and char l => 2
  126. ///
  127. static int countChars(String s, String char, {bool caseSensitive = true}) {
  128. var count = 0;
  129. s.codeUnits.toList().forEach((i) {
  130. if (caseSensitive) {
  131. if (i == char.runes.first) {
  132. count++;
  133. }
  134. } else {
  135. if (i == char.toLowerCase().runes.first ||
  136. i == char.toUpperCase().runes.first) {
  137. count++;
  138. }
  139. }
  140. });
  141. return count;
  142. }
  143. ///
  144. /// Checks if the given string [s] is a digit.
  145. ///
  146. /// Will return false if the given string [s] is empty.
  147. ///
  148. static bool isDigit(String s) {
  149. if (s.isEmpty) {
  150. return false;
  151. }
  152. if (s.length > 1) {
  153. for (var r in s.runes) {
  154. if (r ^ 0x30 > 9) {
  155. return false;
  156. }
  157. }
  158. return true;
  159. } else {
  160. return s.runes.first ^ 0x30 <= 9;
  161. }
  162. }
  163. ///
  164. /// Compares the given strings [a] and [b].
  165. ///
  166. static bool equalsIgnoreCase(String a, String b) =>
  167. a.toLowerCase() == b.toLowerCase();
  168. ///
  169. /// Checks if the given [list] contains the string [s]
  170. ///
  171. static bool inList(String s, List<String> list, {bool ignoreCase = false}) {
  172. for (var l in list) {
  173. if (ignoreCase) {
  174. if (equalsIgnoreCase(s, l)) {
  175. return true;
  176. }
  177. } else {
  178. if (s == l) {
  179. return true;
  180. }
  181. }
  182. }
  183. return false;
  184. }
  185. ///
  186. /// Checks if the given string [s] is a palindrome
  187. /// Example :
  188. /// aha => true
  189. /// hello => false
  190. ///
  191. static bool isPalindrome(String s) {
  192. for (var i = 0; i < s.length / 2; i++) {
  193. if (s[i] != s[s.length - 1 - i]) return false;
  194. }
  195. return true;
  196. }
  197. ///
  198. /// Replaces chars of the given String [s] with [replace].
  199. ///
  200. /// The default value of [replace] is *.
  201. /// [begin] determines the start of the 'replacing'. If [begin] is null, it starts from index 0.
  202. /// [end] defines the end of the 'replacing'. If [end] is null, it ends at [s] length divided by 2.
  203. /// If [s] is empty or consists of only 1 char, the method returns null.
  204. ///
  205. /// Example :
  206. /// 1234567890 => *****67890
  207. /// 1234567890 with begin 2 and end 6 => 12****7890
  208. /// 1234567890 with begin 1 => 1****67890
  209. ///
  210. static String? hidePartial(String s,
  211. {int begin = 0, int? end, String replace = '*'}) {
  212. var buffer = StringBuffer();
  213. if (s.length <= 1) {
  214. return null;
  215. }
  216. if (end == null) {
  217. end = (s.length / 2).round();
  218. } else {
  219. if (end > s.length) {
  220. end = s.length;
  221. }
  222. }
  223. for (var i = 0; i < s.length; i++) {
  224. if (i >= end) {
  225. buffer.write(String.fromCharCode(s.runes.elementAt(i)));
  226. continue;
  227. }
  228. if (i >= begin) {
  229. buffer.write(replace);
  230. continue;
  231. }
  232. buffer.write(String.fromCharCode(s.runes.elementAt(i)));
  233. }
  234. return buffer.toString();
  235. }
  236. ///
  237. /// Add a [char] at a [position] with the given String [s].
  238. ///
  239. /// The boolean [repeat] defines whether to add the [char] at every [position].
  240. /// If [position] is greater than the length of [s], it will return [s].
  241. /// If [repeat] is true and [position] is 0, it will return [s].
  242. ///
  243. /// Example :
  244. /// 1234567890 , '-', 3 => 123-4567890
  245. /// 1234567890 , '-', 3, true => 123-456-789-0
  246. ///
  247. static String addCharAtPosition(String s, String char, int position,
  248. {bool repeat = false}) {
  249. if (!repeat) {
  250. if (s.length < position) {
  251. return s;
  252. }
  253. var before = s.substring(0, position);
  254. var after = s.substring(position, s.length);
  255. return before + char + after;
  256. } else {
  257. if (position == 0) {
  258. return s;
  259. }
  260. var buffer = StringBuffer();
  261. for (var i = 0; i < s.length; i++) {
  262. if (i != 0 && i % position == 0) {
  263. buffer.write(char);
  264. }
  265. buffer.write(String.fromCharCode(s.runes.elementAt(i)));
  266. }
  267. return buffer.toString();
  268. }
  269. }
  270. ///
  271. /// Splits the given String [s] in chunks with the given [chunkSize].
  272. ///
  273. static List<String> chunk(String s, int chunkSize) {
  274. var chunked = <String>[];
  275. for (var i = 0; i < s.length; i += chunkSize) {
  276. var end = (i + chunkSize < s.length) ? i + chunkSize : s.length;
  277. chunked.add(s.substring(i, end));
  278. }
  279. return chunked;
  280. }
  281. ///
  282. /// Picks only required string[value] starting [from] and ending at [to]
  283. ///
  284. /// Example :
  285. /// pickOnly('123456789',from:3,to:7);
  286. /// returns '34567'
  287. ///
  288. static String pickOnly(value, {int from = 1, int to = -1}) {
  289. try {
  290. return value.substring(
  291. from == 0 ? 0 : from - 1, to == -1 ? value.length : to);
  292. } catch (e) {
  293. return value;
  294. }
  295. }
  296. ///
  297. /// Removes character with [index] from a String [value]
  298. ///
  299. /// Example:
  300. /// removeCharAtPosition('flutterr', 8);
  301. /// returns 'flutter'
  302. static String removeCharAtPosition(String value, int index) {
  303. try {
  304. return value.substring(0, -1 + index) +
  305. value.substring(index, value.length);
  306. } catch (e) {
  307. return value;
  308. }
  309. }
  310. ///
  311. ///Remove String[value] with [pattern]
  312. ///
  313. ///[repeat]:boolean => if(true) removes all occurence
  314. ///
  315. ///[casensitive]:boolean => if(true) a != A
  316. ///
  317. ///Example: removeExp('Hello This World', 'This'); returns 'Hello World'
  318. ///
  319. static String removeExp(String value, String pattern,
  320. {bool repeat = true,
  321. bool caseSensitive = true,
  322. bool multiLine = false,
  323. bool dotAll = false,
  324. bool unicode = false}) {
  325. var result = value;
  326. if (repeat) {
  327. result = value
  328. .replaceAll(
  329. RegExp(pattern,
  330. caseSensitive: caseSensitive,
  331. multiLine: multiLine,
  332. dotAll: dotAll,
  333. unicode: unicode),
  334. '')
  335. .replaceAll(RegExp(' +'), ' ')
  336. .trim();
  337. } else {
  338. result = value
  339. .replaceFirst(
  340. RegExp(pattern,
  341. caseSensitive: caseSensitive,
  342. multiLine: multiLine,
  343. dotAll: dotAll,
  344. unicode: unicode),
  345. '')
  346. .replaceAll(RegExp(' +'), ' ')
  347. .trim();
  348. }
  349. return result;
  350. }
  351. ///
  352. /// Takes in a String[value] and truncates it with [length]
  353. /// [symbol] default is '...'
  354. ///truncate('This is a Dart Utility Library', 26)
  355. /// returns 'This is a Dart Utility Lib...'
  356. static String truncate(String value, int length, {String symbol = '...'}) {
  357. var result = value;
  358. try {
  359. result = value.substring(0, length) + symbol;
  360. } catch (e) {
  361. print(e.toString());
  362. }
  363. return result;
  364. }
  365. ///Generates a Random string
  366. ///
  367. ///[length]: length of string,
  368. ///
  369. ///[alphabet]:(boolean) add alphabet to string[uppercase]ABCD and [lowercase]abcd,
  370. ///
  371. ///[numeric]:(boolean) add integers to string like 3622737
  372. ///
  373. ///[special]:(boolean) add special characters like $#@&^
  374. ///
  375. ///[from]:where you want to generate string from
  376. ///
  377. static String generateRandomString(int length,
  378. {alphabet = true,
  379. numeric = true,
  380. special = true,
  381. uppercase = true,
  382. lowercase = true,
  383. String from = ''}) {
  384. var res = '';
  385. do {
  386. res += randomizer(alphabet, numeric, lowercase, uppercase, special, from);
  387. } while (res.length < length);
  388. var possible = res.split('');
  389. possible.shuffle(); //all possible combinations shuffled
  390. var result = [];
  391. for (var i = 0; i < length; i++) {
  392. var randomNumber = Random().nextInt(length);
  393. result.add(possible[randomNumber]);
  394. }
  395. return result.join();
  396. }
  397. static String randomizer(bool alphabet, bool numeric, bool lowercase,
  398. bool uppercase, bool special, String from) {
  399. var a = 'ABCDEFGHIJKLMNOPQRXYZ';
  400. var la = 'abcdefghijklmnopqrxyz';
  401. var b = '0123456789';
  402. var c = '~^!@#\$%^&*;`(=?]:[.)_+-|\{}';
  403. var result = '';
  404. if (alphabet) {
  405. if (lowercase) {
  406. result += la;
  407. }
  408. if (uppercase) {
  409. result += a;
  410. }
  411. if (!uppercase && !lowercase) {
  412. result += a;
  413. result += la;
  414. }
  415. }
  416. if (numeric) {
  417. result += b;
  418. }
  419. if (special) {
  420. result += c;
  421. }
  422. if (from != '') {
  423. //if set return it
  424. result = from;
  425. }
  426. return result;
  427. }
  428. }