String transformation for subject course code for Dart/Flutter - flutter

For interaction with an API, I need to pass the course code in <string><space><number> format. For example, MCTE 2333, CCUB 3621, BTE 1021.
Yes, the text part can be 3 or 4 letters.
Most users enter the code without the space, eg: MCTE2333. But that causes error to the API. So how can I add a space between string and numbers so that it follows the correct format.

You can achieve the desired behaviour by using regular expressions:
void main() {
String a = "MCTE2333";
String aStr = a.replaceAll(RegExp(r'[^0-9]'), ''); //extract the number
String bStr = a.replaceAll(RegExp(r'[^A-Za-z]'), ''); //extract the character
print("$bStr $aStr"); //MCTE 2333
}
Note: This will produce the same result, regardless of how many whitespaces your user enters between the characters and numbers.

Try this.You have to give two texfields. One is for name i.e; MCTE and one is for numbers i.e; 1021. (for this textfield you have to change keyboard type only number).
After that you can join those string with space between them and send to your DB.
It's just like hack but it will work.

Scrolling down the course codes list, I noticed some unusual formatting.
Example: TQB 1001E, TQB 1001E etc. (With extra letter at the end)
So, this special format doesn't work with #Jahidul Islam's answer. However, inspired by his answer, I manage to come up with this logic:
var code = "TQB2001M";
var i = course.indexOf(RegExp(r'[^A-Za-z]')); // get the index
var j = course.substring(0, i); // extract the first half
var k = course.substring(i).trim(); // extract the others
var formatted = '$j $k'.toUpperCase(); // combine & capitalize
print(formatted); // TQB 1011M
Works with other formats too. Check out the DartPad here.

Here is the entire logic you need (also works for multiple whitespaces!):
void main() {
String courseCode= "MMM 111";
String parsedCourseCode = "";
if (courseCode.contains(" ")) {
final ensureSingleWhitespace = RegExp(r"(?! )\s+| \s+");
parsedCourseCode = courseCode.split(ensureSingleWhitespace).join(" ");
} else {
final r1 = RegExp(r'[0-9]', caseSensitive: false);
final r2 = RegExp(r'[a-z]', caseSensitive: false);
final letters = courseCode.split(r1);
final numbers = courseCode.split(r2);
parsedCourseCode = "${letters[0].trim()} ${numbers.last}";
}
print(parsedCourseCode);
}
Play around with the input value (courseCode) to test it - also use dart pad if you want. You just have to add this logic to your input value, before submitting / handling the input form of your user :)

Related

How to display Unicode Smiley from json response dynamically in flutter

How to display Unicode Smiley from json response dynamically in flutter. It's display properly when i declare string as a static but from dynamic response it's not display smiley properly.
Static Declaration: (Working)
child: Text("\ud83d\ude0e\ud83d\ude0eThis is just test notification..\ud83d\ude0e\ud83d\ude0e\ud83d\udcaf\ud83d\ude4c")
Dynamic Response:
"message":"\\ud83d\\ude4c Be Safe at your home \\ud83c\\udfe0",
When i'm parse and pass this response to Text then it's consider Unicode as a String and display as a string instead of Smiley Code is below to display text with smiley:
child: Text(_listData[index].message.toString().replaceAll("\\\\", "\\"))
Already go through this: Question but it's only working when single unicode not working with multiple unicode.
Anyone worked with text along with unicode caracter display dynamically then please let me know.
Another alternate Good Solution I would give to unescape characters is this:
1st ->
String s = "\\ud83d\\ude0e Be Safe at your home \\ud83c\\ude0e";
String q = s.replaceAll("\\\\", "\\");
This would print and wont be able to escape characters:
\ud83d\ud83d Be Safe at your home \ud83c\ud83d
and above would be the output.
So what one can do is either unescape them while parsing or use:
String convertStringToUnicode(String content) {
String regex = "\\u";
int offset = content.indexOf(regex) + regex.length;
while(offset > 1){
int limit = offset + 4;
String str = content.substring(offset, limit);
// print(str);
if(str!=null && str.isNotEmpty){
String uni = String.fromCharCode(int.parse(str,radix:16));
content = content.replaceFirst(regex+str,uni);
// print(content);
}
offset = content.indexOf(regex) + regex.length;
// print(offset);
}
return content;
}
This will replace and convert all the literals into unicode characters and result and output of emoji:
String k = convertStringToUnicode(q);
print(k);
😎 Be Safe at your home 🈎
That is above would be the output.
Note: above answer given would just work as good but this is just when you want to have an unescape function and don't need to use third-party libraries.
You can extend this using switch cases with multiple unescape solutions.
Issue resolved by using below code snippet.
Client client = Client();
final response = await client.get(Uri.parse('YOUR_API_URL'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
final extractedData = json.decode(response.body.replaceAll("\\\\", "\\"));
}
Here we need to replace double backslash to single backslash and then decode JSON respone before set into Text like this we can display multiple unicode like this:
final extractedData = json.decode(response.body.replaceAll("\\",
"\"));
Hope this answer help to other

Extracting String in Regex in Flutter and Converting it To Int

I have this Flutter bit of code here, which is a large String. It would be different every time, but the format would stay the same since it's a template:
"William\nWilliam description here...\n$^170^ usd" + Uuid().v4()
I want to extract the 170 part, and then convert it to interger, so I can remove it from list of ints. I have tried a lot of code, but it isn't working for a few reasons, one is I can't extract the actual number from the String between the ^ and ^, and then I can't convert it to interger. Here's the try function (incomplete).
deleteSumItem(item) {
final regEx = RegExp(r'\^\d+(?:\^\d+)?'); //not sure if this is right regex for the String template
final priceValueMatch = regEx.firstMatch(item); //this doesn't return the particular number extracted
_totalPrice.remove(priceValueMatch); //i get error here that it isn't a int
_counter = _counter - priceValueMatch; //then remove it from interger as int
}
The function would take that String ("William\nWilliam description here...\n$^170^ usd" + Uuid().v4()) template (the number would be different between the ^ ^, but the template is same), then convert it to interger and remove from list as int.
Try the following:
void main() {
RegExp regExp = RegExp(r'\^(\d+)\^');
String input = r"William\nWilliam description here...\n$^170^ usd";
String match = regExp.firstMatch(input).group(1);
print(match); // 170
int number = int.parse(match);
print(number); // 170
}
I have changed the RegExp so it does correctly capture the number in its own capture group. It looked like you got a little confused in the process of creating the RegExp but it could also be I am missing some details about the problem.

Reliably Extracting String In Flutter List Every Time

So I have a quite interesting exercise I've been trying to solve for a while now, but haven't come up with a reliable solution, so I thought you guys could help me out. I have this String that is composed of few random custom parts, for example:
"William\nWilliam description here...\n$170.00 usd") + Uuid().v4();
I need to extract the part after '$' and '.', in this case 170, but it can be any number between.
UPDATE
as I said in the last comment, if I wanted to do it in a function (find the price only), it could go something like this:
deleteSumItem(item) {
final regEx = RegExp(r'\$\d+(?:\.\d+)?');
const textToSearch = r'item';
final priceValueMatch = regEx.firstMatch(textToSearch);
print(priceValueMatch.group(0));
_totalPrice.remove(priceValueMatch);
_counter = _counter - priceValueMatch; //getting error here to convert to num
//but int.parse won't work either, then I get the String error
//RegExp can't be assigned to paremeter String
}
Also, this function returns null for regex, so there is some mistake I'm making, any thoughts?
deleteSumItem(item) {
final regEx = RegExp(r'\1\d+(?:\.\d+)?');
final priceValueMatch = regEx.firstMatch(r'item');
print('THIS IS REGEX: $priceValueMatch');} //priceValueMatch returns null
fix
deleteSumItem(item) {
RegExp regExp = RegExp(r'\^(\d+)\^');
String input = item;
String match = regExp.firstMatch("r" + '"' + input + '"').group(1);
print('Match: $match');
int number = int.parse(match);
print('Number: $number');
_totalPrice.remove(number);
_counter = _counter - number;}
Assuming you can answer 'yes' to the questions in my above comment, you can simply use regular expressions to find the price value in your string:
final regEx = RegExp(r'\$\d+(?:\.\d+)?');
const textToSearch = r'William\nWilliam description here...\n$170.00 cm';
final priceValueMatch = regEx.firstMatch(textToSearch);
print(priceValueMatch.group(0)); // this will print $170.00
The regular expression is looking for a dollar sign \$ followed by 1 or more digits d+ followed by optional decimal point and optional digits behind that decimal (?:\.\d+)?.
This actually ignores a lot of the questions in my above comment. This simply looks for a price value preceded by a dollar sign within the string you give it.
Here is another approach based on your comments. This is assuming the new line characters will always exist
const textToSearch = 'William\nWilliam description here...\n170.00 cm';
final lines = textToSearch.split('\n'); // Split on new line character
// If your template is always the same,
// then your number will be at the start of line 3:
print(lines[2]); // Will print: 170.00 cm
// If you want just your 170 value then:
final regEx = RegExp(r'\d+');
final priceValueMatch = regEx.firstMatch(lines[2]);
final priceInt = int.parse(priceValueMatch.group(0));
print(priceInt); // Will print: 170

Searching sembast data both caps and small letters

I am using sembast package for local data storage for a flutter app. When I search through the local data, I want to get the results regardless of whether letters are in caps or small. My current code is sensitive to capital and small letters.
Future searchFoodByField(String fieldName, String searchItem) async {
var finder = Finder(filter: Filter.matches(fieldName, searchItem));
final recordSnapshots = await _foodStore.find(
await _db,
finder: finder,
);
return recordSnapshots.map((snapshot) {
final food = Food.fromMap(snapshot.value);
food.foodId = snapshot.key;
return food;
}).toList();
}
How can it be modified to get the desired outcome?
I'm assuming you want to look for the exact word. For non-english language, you might also want to remove the accent. (diacritic package can help help here).
// Using a regular expression matching the exact word (no case)
var filter = Filter.matchesRegExp(
fieldName, RegExp('^$searchItem\$', caseSensitive: false));
You can also use a custom filter, to perform any filtering you want:
// Using a custom filter exact word (converting everything to lowercase)
searchItem = searchItem.toLowerCase();
filter = Filter.custom((snapshot) {
var value = snapshot[fieldName] as String;
return value?.toLowerCase() == searchItem;
});

How to replace part of string with asterisk in Flutter?

I want to replace part of the string with asterisk (* sign).
How can I achieve that? Been searching around but I can't find a solution for it.
For example, I getting 0123456789 from backend, but I want to display it as ******6789 only.
Please advise.
Many thanks.
Try this:
void main(List<String> arguments) {
String test = "0123456789";
int numSpace = 6;
String result = test.replaceRange(0, numSpace, '*' * numSpace);
print("original: ${test} replaced: ${result}");
}
Notice in dart the multiply operator can be used against string, which basically just creates N version of the string. So in the example, we are padding the string 6 times with'*'.
Output:
original: 0123456789 replaced: ******6789
try using replaceRange. It works like magic, no need for regex. its replaces your range of values with a string of your choice.
//for example
prefixMomoNum = prefs.getString("0267268224");
prefixMomoNum = prefixMomoNum.replaceRange(3, 6, "****");
//Output 026****8224
You can easily achieve it with a RegExp that matches all characters but the last n char.
Example:
void main() {
String number = "123456789";
String secure = number.replaceAll(RegExp(r'.(?=.{4})'),'*'); // here n=4
print(secure);
}
Output: *****6789
Hope that helps!