import 'dart:convert';
|
|
import 'dart:math';
|
|
|
|
///
|
|
/// Helper class for String operations
|
|
///
|
|
class StringUtils {
|
|
static AsciiCodec asciiCodec = const AsciiCodec();
|
|
|
|
///
|
|
/// Returns the given string or the default string if the given string is null
|
|
///
|
|
static String defaultString(String? str, {String defaultStr = ''}) {
|
|
return str ?? defaultStr;
|
|
}
|
|
|
|
///
|
|
/// Checks if the given String [s] is null or empty
|
|
///
|
|
static bool isNullOrEmpty(String? s) =>
|
|
(s == null || s.isEmpty) ? true : false;
|
|
|
|
///
|
|
/// Checks if the given String [s] is not null or empty
|
|
///
|
|
static bool isNotNullOrEmpty(String? s) => !isNullOrEmpty(s);
|
|
|
|
///
|
|
/// Transfers the given String [s] from camcelCase to upperCaseUnderscore
|
|
/// Example : helloWorld => HELLO_WORLD
|
|
///
|
|
static String camelCaseToUpperUnderscore(String s) {
|
|
var sb = StringBuffer();
|
|
var first = true;
|
|
s.runes.forEach((int rune) {
|
|
var char = String.fromCharCode(rune);
|
|
if (isUpperCase(char) && !first) {
|
|
sb.write('_');
|
|
sb.write(char.toUpperCase());
|
|
} else {
|
|
first = false;
|
|
sb.write(char.toUpperCase());
|
|
}
|
|
});
|
|
return sb.toString();
|
|
}
|
|
|
|
///
|
|
/// Transfers the given String [s] from camcelCase to lowerCaseUnderscore
|
|
/// Example : helloWorld => hello_world
|
|
///
|
|
static String camelCaseToLowerUnderscore(String s) {
|
|
var sb = StringBuffer();
|
|
var first = true;
|
|
s.runes.forEach((int rune) {
|
|
var char = String.fromCharCode(rune);
|
|
if (isUpperCase(char) && !first) {
|
|
if (char != '_') {
|
|
sb.write('_');
|
|
}
|
|
sb.write(char.toLowerCase());
|
|
} else {
|
|
first = false;
|
|
sb.write(char.toLowerCase());
|
|
}
|
|
});
|
|
return sb.toString();
|
|
}
|
|
|
|
///
|
|
/// Checks if the given string [s] is lower case
|
|
///
|
|
static bool isLowerCase(String s) {
|
|
return s == s.toLowerCase();
|
|
}
|
|
|
|
///
|
|
/// Checks if the given string [s] is upper case
|
|
///
|
|
static bool isUpperCase(String s) {
|
|
return s == s.toUpperCase();
|
|
}
|
|
|
|
///
|
|
/// Checks if the given string [s] contains only ascii chars
|
|
///
|
|
static bool isAscii(String s) {
|
|
try {
|
|
asciiCodec.decode(s.codeUnits);
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///
|
|
/// Capitalize the given string [s]. If [allWords] is set to true, it will capitalize all words within the given string [s].
|
|
///
|
|
/// The string [s] is there fore splitted by " " (space).
|
|
///
|
|
/// Example :
|
|
///
|
|
/// * [s] = "world" => World
|
|
/// * [s] = "WORLD" => World
|
|
/// * [s] = "the quick lazy fox" => The quick lazy fox
|
|
/// * [s] = "the quick lazy fox" and [allWords] = true => The Quick Lazy Fox
|
|
///
|
|
static String capitalize(String s, {bool allWords = false}) {
|
|
if (s.isEmpty) {
|
|
return '';
|
|
}
|
|
s = s.trim();
|
|
if (allWords) {
|
|
var words = s.split(' ');
|
|
var capitalized = [];
|
|
for (var w in words) {
|
|
capitalized.add(capitalize(w));
|
|
}
|
|
return capitalized.join(' ');
|
|
} else {
|
|
return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Reverse the given string [s]
|
|
/// Example : hello => olleh
|
|
///
|
|
static String reverse(String s) {
|
|
return String.fromCharCodes(s.runes.toList().reversed);
|
|
}
|
|
|
|
///
|
|
/// Counts how offen the given [char] apears in the given string [s].
|
|
/// The value [caseSensitive] controlls whether it should only look for the given [char]
|
|
/// or also the equivalent lower/upper case version.
|
|
/// Example: Hello and char l => 2
|
|
///
|
|
static int countChars(String s, String char, {bool caseSensitive = true}) {
|
|
var count = 0;
|
|
s.codeUnits.toList().forEach((i) {
|
|
if (caseSensitive) {
|
|
if (i == char.runes.first) {
|
|
count++;
|
|
}
|
|
} else {
|
|
if (i == char.toLowerCase().runes.first ||
|
|
i == char.toUpperCase().runes.first) {
|
|
count++;
|
|
}
|
|
}
|
|
});
|
|
return count;
|
|
}
|
|
|
|
///
|
|
/// Checks if the given string [s] is a digit.
|
|
///
|
|
/// Will return false if the given string [s] is empty.
|
|
///
|
|
static bool isDigit(String s) {
|
|
if (s.isEmpty) {
|
|
return false;
|
|
}
|
|
if (s.length > 1) {
|
|
for (var r in s.runes) {
|
|
if (r ^ 0x30 > 9) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
return s.runes.first ^ 0x30 <= 9;
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Compares the given strings [a] and [b].
|
|
///
|
|
static bool equalsIgnoreCase(String a, String b) =>
|
|
a.toLowerCase() == b.toLowerCase();
|
|
|
|
///
|
|
/// Checks if the given [list] contains the string [s]
|
|
///
|
|
static bool inList(String s, List<String> list, {bool ignoreCase = false}) {
|
|
for (var l in list) {
|
|
if (ignoreCase) {
|
|
if (equalsIgnoreCase(s, l)) {
|
|
return true;
|
|
}
|
|
} else {
|
|
if (s == l) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
///
|
|
/// Checks if the given string [s] is a palindrome
|
|
/// Example :
|
|
/// aha => true
|
|
/// hello => false
|
|
///
|
|
static bool isPalindrome(String s) {
|
|
for (var i = 0; i < s.length / 2; i++) {
|
|
if (s[i] != s[s.length - 1 - i]) return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
///
|
|
/// Replaces chars of the given String [s] with [replace].
|
|
///
|
|
/// The default value of [replace] is *.
|
|
/// [begin] determines the start of the 'replacing'. If [begin] is null, it starts from index 0.
|
|
/// [end] defines the end of the 'replacing'. If [end] is null, it ends at [s] length divided by 2.
|
|
/// If [s] is empty or consists of only 1 char, the method returns null.
|
|
///
|
|
/// Example :
|
|
/// 1234567890 => *****67890
|
|
/// 1234567890 with begin 2 and end 6 => 12****7890
|
|
/// 1234567890 with begin 1 => 1****67890
|
|
///
|
|
static String? hidePartial(String s,
|
|
{int begin = 0, int? end, String replace = '*'}) {
|
|
var buffer = StringBuffer();
|
|
if (s.length <= 1) {
|
|
return null;
|
|
}
|
|
if (end == null) {
|
|
end = (s.length / 2).round();
|
|
} else {
|
|
if (end > s.length) {
|
|
end = s.length;
|
|
}
|
|
}
|
|
for (var i = 0; i < s.length; i++) {
|
|
if (i >= end) {
|
|
buffer.write(String.fromCharCode(s.runes.elementAt(i)));
|
|
continue;
|
|
}
|
|
if (i >= begin) {
|
|
buffer.write(replace);
|
|
continue;
|
|
}
|
|
buffer.write(String.fromCharCode(s.runes.elementAt(i)));
|
|
}
|
|
return buffer.toString();
|
|
}
|
|
|
|
///
|
|
/// Add a [char] at a [position] with the given String [s].
|
|
///
|
|
/// The boolean [repeat] defines whether to add the [char] at every [position].
|
|
/// If [position] is greater than the length of [s], it will return [s].
|
|
/// If [repeat] is true and [position] is 0, it will return [s].
|
|
///
|
|
/// Example :
|
|
/// 1234567890 , '-', 3 => 123-4567890
|
|
/// 1234567890 , '-', 3, true => 123-456-789-0
|
|
///
|
|
static String addCharAtPosition(String s, String char, int position,
|
|
{bool repeat = false}) {
|
|
if (!repeat) {
|
|
if (s.length < position) {
|
|
return s;
|
|
}
|
|
var before = s.substring(0, position);
|
|
var after = s.substring(position, s.length);
|
|
return before + char + after;
|
|
} else {
|
|
if (position == 0) {
|
|
return s;
|
|
}
|
|
var buffer = StringBuffer();
|
|
for (var i = 0; i < s.length; i++) {
|
|
if (i != 0 && i % position == 0) {
|
|
buffer.write(char);
|
|
}
|
|
buffer.write(String.fromCharCode(s.runes.elementAt(i)));
|
|
}
|
|
return buffer.toString();
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Splits the given String [s] in chunks with the given [chunkSize].
|
|
///
|
|
static List<String> chunk(String s, int chunkSize) {
|
|
var chunked = <String>[];
|
|
for (var i = 0; i < s.length; i += chunkSize) {
|
|
var end = (i + chunkSize < s.length) ? i + chunkSize : s.length;
|
|
chunked.add(s.substring(i, end));
|
|
}
|
|
return chunked;
|
|
}
|
|
|
|
///
|
|
/// Picks only required string[value] starting [from] and ending at [to]
|
|
///
|
|
/// Example :
|
|
/// pickOnly('123456789',from:3,to:7);
|
|
/// returns '34567'
|
|
///
|
|
static String pickOnly(value, {int from = 1, int to = -1}) {
|
|
try {
|
|
return value.substring(
|
|
from == 0 ? 0 : from - 1, to == -1 ? value.length : to);
|
|
} catch (e) {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
///
|
|
/// Removes character with [index] from a String [value]
|
|
///
|
|
/// Example:
|
|
/// removeCharAtPosition('flutterr', 8);
|
|
/// returns 'flutter'
|
|
static String removeCharAtPosition(String value, int index) {
|
|
try {
|
|
return value.substring(0, -1 + index) +
|
|
value.substring(index, value.length);
|
|
} catch (e) {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
///
|
|
///Remove String[value] with [pattern]
|
|
///
|
|
///[repeat]:boolean => if(true) removes all occurence
|
|
///
|
|
///[casensitive]:boolean => if(true) a != A
|
|
///
|
|
///Example: removeExp('Hello This World', 'This'); returns 'Hello World'
|
|
///
|
|
static String removeExp(String value, String pattern,
|
|
{bool repeat = true,
|
|
bool caseSensitive = true,
|
|
bool multiLine = false,
|
|
bool dotAll = false,
|
|
bool unicode = false}) {
|
|
var result = value;
|
|
if (repeat) {
|
|
result = value
|
|
.replaceAll(
|
|
RegExp(pattern,
|
|
caseSensitive: caseSensitive,
|
|
multiLine: multiLine,
|
|
dotAll: dotAll,
|
|
unicode: unicode),
|
|
'')
|
|
.replaceAll(RegExp(' +'), ' ')
|
|
.trim();
|
|
} else {
|
|
result = value
|
|
.replaceFirst(
|
|
RegExp(pattern,
|
|
caseSensitive: caseSensitive,
|
|
multiLine: multiLine,
|
|
dotAll: dotAll,
|
|
unicode: unicode),
|
|
'')
|
|
.replaceAll(RegExp(' +'), ' ')
|
|
.trim();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
///
|
|
/// Takes in a String[value] and truncates it with [length]
|
|
/// [symbol] default is '...'
|
|
///truncate('This is a Dart Utility Library', 26)
|
|
/// returns 'This is a Dart Utility Lib...'
|
|
static String truncate(String value, int length, {String symbol = '...'}) {
|
|
var result = value;
|
|
|
|
try {
|
|
result = value.substring(0, length) + symbol;
|
|
} catch (e) {
|
|
print(e.toString());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
///Generates a Random string
|
|
///
|
|
///[length]: length of string,
|
|
///
|
|
///[alphabet]:(boolean) add alphabet to string[uppercase]ABCD and [lowercase]abcd,
|
|
///
|
|
///[numeric]:(boolean) add integers to string like 3622737
|
|
///
|
|
///[special]:(boolean) add special characters like $#@&^
|
|
///
|
|
///[from]:where you want to generate string from
|
|
///
|
|
static String generateRandomString(int length,
|
|
{alphabet = true,
|
|
numeric = true,
|
|
special = true,
|
|
uppercase = true,
|
|
lowercase = true,
|
|
String from = ''}) {
|
|
var res = '';
|
|
|
|
do {
|
|
res += randomizer(alphabet, numeric, lowercase, uppercase, special, from);
|
|
} while (res.length < length);
|
|
|
|
var possible = res.split('');
|
|
possible.shuffle(); //all possible combinations shuffled
|
|
var result = [];
|
|
|
|
for (var i = 0; i < length; i++) {
|
|
var randomNumber = Random().nextInt(length);
|
|
result.add(possible[randomNumber]);
|
|
}
|
|
|
|
return result.join();
|
|
}
|
|
|
|
static String randomizer(bool alphabet, bool numeric, bool lowercase,
|
|
bool uppercase, bool special, String from) {
|
|
var a = 'ABCDEFGHIJKLMNOPQRXYZ';
|
|
var la = 'abcdefghijklmnopqrxyz';
|
|
var b = '0123456789';
|
|
var c = '~^!@#\$%^&*;`(=?]:[.)_+-|\{}';
|
|
var result = '';
|
|
|
|
if (alphabet) {
|
|
if (lowercase) {
|
|
result += la;
|
|
}
|
|
if (uppercase) {
|
|
result += a;
|
|
}
|
|
|
|
if (!uppercase && !lowercase) {
|
|
result += a;
|
|
result += la;
|
|
}
|
|
}
|
|
if (numeric) {
|
|
result += b;
|
|
}
|
|
|
|
if (special) {
|
|
result += c;
|
|
}
|
|
|
|
if (from != '') {
|
|
//if set return it
|
|
result = from;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|