Extract template tags {{..}} from a string in flutter - flutter

I need to extract squiggly bracketed template tags from a string. For example:
String str="Hello {{user}}, your reference is {{ref}}"
I would like a to extract the tags in-between the {{..}} into an List. For example:
["user","ref"]
How can I do this, for example with a Regx - I would need to ignore any whitespace in-side the brackets for example {{ user}} would need to return "user".
This question is exactly same as this que.. Want code for flutter dart.

You can use this regex
void main() {
RegExp re = RegExp(r'{{([^]*?)}}');
String data = "Hello {{user}}, your reference is {{ref}}";
var match = re.firstMatch(data);
if (match != null) print(match.group(1));
List something = re.allMatches(data).map((m)=>m[1]).toList();
print(something);
}
OUtput
user
[user, ref]

void main() {
String str="Hello {{user}}, your reference is {{ref}}";
List<String> lstr = getStringBetweenBracket(str);
print(lstr);
}
List<String> getStringBetweenBracket(String str) {
List<String> rstr = [];
var j = str.splitMapJoin(new RegExp(r'\{\{(.*?)\}\}'), onMatch: (e) {
if( e.group(0) != null)
return e.group(0)!.replaceAll("{{","").replaceAll("}}","")+",";
else
return "";
}, onNonMatch: (e) { return ""; });
if(j != "") {
rstr = j.split(",");
rstr.removeAt(rstr.length-1);
}
return rstr;
}

you can do this way get array of data
void main() {
String str="Hello {{user}}, your reference is {{ref}}";
var parts = str.split(' ');
print(parts);
print(parts[1]);
}
void main(){
String str = 'HelloTutorialKart.';
int startIndex = 5;
int endIndex = 13;
//find substring
String result = str.substring(startIndex, endIndex);
print(result);
}
output
Tutorial

Related

How to replace n occurrence of a substring in a string in dart?

I want to replace n occurrence of a substring in a string.
myString = "I have a mobile. I have a cat.";
How I can replace the second have of myString
hope this simple function helps. You can also extract the function contents if you don't wish a function. It's just two lines with some
Dart magic
void main() {
String myString = 'I have a mobile. I have a cat.';
String searchFor='have';
int replaceOn = 2;
String replaceText = 'newhave';
String result = customReplace(myString,searchFor,replaceOn,replaceText);
print(result);
}
String customReplace(String text,String searchText, int replaceOn, String replaceText){
Match result = searchText.allMatches(text).elementAt(replaceOn - 1);
return text.replaceRange(result.start,result.end,replaceText);
}
Something like that should work:
String replaceNthOccurrence(String input, int n, String from, String to) {
var index = -1;
while (--n >= 0) {
index = input.indexOf(from, ++index);
if (index == -1) {
break;
}
}
if (index != -1) {
var result = input.replaceFirst(from, to, index);
return result;
}
return input;
}
void main() {
var myString = "I have a mobile. I have a cat.";
var replacedString = replaceNthOccurrence(myString, 2, "have", "had");
print(replacedString); // prints "I have a mobile. I had a cat."
}
This would be a better solution to undertake as it check the fallbacks also. Let me list down all the scenarios:
If position is 0 then it will replace all occurrence.
If position is correct then it will replace at same location.
If position is wrong then it will send back input string.
If substring does not exist in input then it will send back input string.
void main() {
String input = "I have a mobile. I have a cat.";
print(replacenth(input, 'have', 'need', 1));
}
/// Computes the nth string replace.
String replacenth(String input, String substr, String replstr,int position) {
if(input.contains(substr))
{
var splittedStr = input.split(substr);
if(splittedStr.length == 0)
return input;
String finalStr = "";
for(int i = 0; i < splittedStr.length; i++)
{
finalStr += splittedStr[i];
if(i == (position - 1))
finalStr += replstr;
else if(i < (splittedStr.length - 1))
finalStr += substr;
}
return finalStr;
}
return input;
}
let's try with this
void main() {
var myString = "I have a mobile. I have a cat.I have a cat";
print(replaceInNthOccurrence(myString, "have", "test", 1));
}
String replaceInNthOccurrence(
String stringToChange, String searchingWord, String replacingWord, int n) {
if(n==1){
return stringToChange.replaceFirst(searchingWord, replacingWord);
}
final String separator = "#######";
String splittingString =
stringToChange.replaceAll(searchingWord, separator + searchingWord);
var splitArray = splittingString.split(separator);
print(splitArray);
String result = "";
for (int i = 0; i < splitArray.length; i++) {
if (i % n == 0) {
splitArray[i] = splitArray[i].replaceAll(searchingWord, replacingWord);
}
result += splitArray[i];
}
return result;
}
here the regex
void main() {
var myString = "I have a mobile. I have a cat. I have a cat. I have a cat.";
final newString =
myString.replaceAllMapped(new RegExp(r'^(.*?(have.*?){3})have'), (match) {
return '${match.group(1)}';
});
print(newString.replaceAll(" "," had "));
}
Demo link
Here it is one more variant which allows to replace any occurrence in subject string.
void main() {
const subject = 'I have a dog. I have a cat. I have a bird.';
final result = replaceStringByOccurrence(subject, 'have', '*have no*', 0);
print(result);
}
/// Looks for `occurrence` of `search` in `subject` and replace it with `replace`.
///
/// The occurrence index is started from 0.
String replaceStringByOccurrence(
String subject, String search, String replace, int occurence) {
if (occurence.isNegative) {
throw ArgumentError.value(occurence, 'occurrence', 'Cannot be negative');
}
final regex = RegExp(r'have');
final matches = regex.allMatches(subject);
if (occurence >= matches.length) {
throw IndexError(occurence, matches, 'occurrence',
'Cannot be more than count of matches');
}
int index = -1;
return subject.replaceAllMapped(regex, (match) {
index += 1;
return index == occurence ? replace : match.group(0)!;
});
}
Tested on dartpad.

Comparing list with another list items and returning it if it has similar items

class Object1 {
final String id;
List<Object1list> lists = [];
Object1({this.id, this.lists});
class Object1list {
final String id;
final String item;
Object1list({this.id});
}
List<String> searchlist = ['object1','object2','object3'];
What i want to do is I want to search "object1list" items for "any" matches with "searchlist" items and
return it as contain function but I don't know how, something like:
return ???.contains(???)
Can somebody help me?
The below function will help you to get matched items:
bool doSearch(List<String> searchlist, List<String> lists) {
List<String> matched = [];
for (String s in searchlist) {
if (lists.contains(s)) {
matched.add(s);
}
//else {
// return false; // Uncomment these lines if you want "lists" to contain all searched items
//}
}
return matched.length > 0; // This for 0 or more items matched
}
Other ways:
import 'package:enumerable/enumerable.dart';
void main() {
final result1 = searchlist.isNotEmpty
? searchlist.distinct().length == searchlist.length
: false;
print(result1);
// OR
final result2 = searchlist.isNotEmpty
? searchlist.toSet().length == searchlist.length
: false;
print(result2);
}
List<String> searchlist = ['object1', 'object2', 'object3', 'object2'];

How to format to json with difference between comma of data/key and comma from text?

I am trying to improve this code so that it can handle a specific case.
Currently it works, unless the user adds a text with a comma
Here is my input who work (look only "note" key/value)
Input_OK = 2020-11-25,note:my text,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14
In this case : my text is ok because there is no comma
Input_NOK = 2020-11-25,note:my text, doesn't work,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14
In this case : my text, doesn't work is not ok because there is comma
With this specific input 2020-11-25,note:my text, work now,2020-11-25,today:2020-11-25,2020-09-14,start:2020-09-14
I try to have this output
[{"release_date":"2020-11-25","today":"2020-11-25","note0":"my text, work now"},{"release_date":"2020-09-14","start":"2020-09-14"}]
Here is my current code
// before this input I add string to a list<String> for each date like that [2020-11-25,note0:test, 2020-11-24,my text, with comma, 2020-11-15,today:2020-11-15, 2020-09-14,start:2020-09-14]
//After I remove space and [ ]
// myinput 2020-11-25,today:2020-11-25,2020-11-25,note0:my text, with comma,2020-09-14,start:2020-09-14
var inputItarable = myinput.toString().split(',').where((s) => s.isNotEmpty);
print("inputItarable ${inputItarable} ");
//inputItarable [2020-11-25, today:2020-11-25, 2020-11-25, note0:my text, with comma, 2020-09-14, start:2020-09-14]
var i = inputItarable.iterator;
var tmp = {};
while (i.moveNext()) {
var key = i.current; i.moveNext();
var value = i.current.split(':');
(tmp[key] ??= []).add(value);
}
var output1 = tmp.keys.map((key) {
var map = {}; map['release_date'] = key;
tmp[key].forEach((e) => map[e[0]] = e[1]);
return map;
}).toList();
var output2=json.encode(output1);
print("output2 $output2 ");
// output2 [{"release_date":"2020-11-25","today":"2020-11-25","note0":"my text, with comma"},{"release_date":"2020-09-14","start":"2020-09-14"}]
[Edit] I have a spécific case, where user back ligne, and have an input like that
myinput 2020-11-25,today:2020-11-25,2020-11-25,note0:my text,
with comma,2020-09-14,start:2020-09-14
in this example I don't know how to replace the back ligne between my text, and with comma by my text,\nwith comma
Please check the code below or you may directly run it on Dartpad at https://dartpad.dev/1404509cc0b427b1f31705448b5edba3
I have written a sanitize function. What the sanitize function does is it sanitizes the text between the possibleStart and possibleEnd. Meaning it replaces all the commas in user input text with §. To do this it assumes that the user input starts with ,note: or ,note0: and ends with ,2020- or ,2021-. This sanitized string is passed to your code and in the end § is replaced with ",". Let me know if you have any questions.
import 'dart:convert';
String sanitize(
String input, List<String> possibleStart, List<String> possibleEnd) {
final String start = possibleStart.join("|");
final String end = possibleEnd.join("|");
final RegExp exp = RegExp("(?<=$start)(.*?)(?=$end)");
final Iterable<Match> matches = exp.allMatches(input);
matches.forEach((match) {
input =
input.replaceFirst(match.group(0), match.group(0).replaceAll(",", "§"));
return true;
});
return input;
}
void main() {
String myinput =
"2020-11-25,today:2020-11-25,2020-11-25,note0:my text, with comma,2020-09-14,start:2020-09-14";
myinput = sanitize(myinput, [",note:", "note\\d:"], [",20\\d\\d-"]);
var inputItarable = myinput.toString().split(',').where((s) => s.isNotEmpty);
print("inputItarable ${inputItarable} ");
//inputItarable [2020-11-25, today:2020-11-25, 2020-11-25, note0:my text, with comma, 2020-09-14, start:2020-09-14]
var i = inputItarable.iterator;
var tmp = {};
while (i.moveNext()) {
var key = i.current;
i.moveNext();
var value = i.current.split(':');
(tmp[key] ??= []).add(value);
}
var output1 = tmp.keys.map((key) {
var map = {};
map['release_date'] = key;
tmp[key].forEach((e) => map[e[0]] = e[1]);
return map;
}).toList();
var output2 = json.encode(output1).replaceAll("§", ",");
print("output2 $output2 ");
}

Filter out a range of characters in dart

I have a string like <p>[var # example] <h1>Title</h1>[visual compose]</p>I want to filter out all the substrings which are inside square brackets, including the square brackets.
Do you mean you want to remove them?
You can do it with RegExp, but I would use a parser when html is involved.
One solution is this:
https://dartpad.dartlang.org/a92f2181191e23ee587d57fb55246c1f
String filterShortcodes(String input,
{String opening = '[', String closing = ']'}) {
assert(opening.runes.length == 1);
assert(closing.runes.length == 1);
final openingRune = opening.runes.first;
final closingRune = closing.runes.first;
bool filter = false;
final buf = StringBuffer();
for (final rune in input.runes) {
if (filter == false && rune == openingRune) {
filter = true;
} else if (filter == true && rune == closingRune) {
filter = false;
} else if (!filter) {
buf.write(String.fromCharCode(rune));
}
}
return buf.toString();
}
void main() {
var input = '<p>[var # example] <h1>Title</h1>[visual compose]</p>';
print(filterShortcodes(input)); // <p> <h1>Title</h1></p>
}
String removeTextBetweenSquareBrackets(String input) {
return input.replaceAll(new RegExp(r'\[.*?\]'), "");
}
void main() {
print(removeTextBetweenSquareBrackets('<p>[var # example] <h1>Title</h1>[visual compose]</p>'));
}

Format string to phone number with (123) 456-6789 pattern using dart

Here is my code
void main() {
String phoneNumber = '123456789';
String formattedPhoneNumber = phoneNumber.replaceFirst("(\d{3})(\d{3})(\d+)", "(\$1) \$2-\$3");
print('Formatted number ${formattedPhoneNumber}');
}
Output:
Formatted number 123456789
I want output as Formatted number (123) 456-6789
Try this
print('1234567890'.replaceAllMapped(RegExp(r'(\d{3})(\d{3})(\d+)'), (Match m) => "(${m[1]}) ${m[2]}-${m[3]}"));
Create a custom Masked class
import 'package:flutter/material.dart';
class MaskedTextController extends TextEditingController {
MaskedTextController({String text, this.mask, Map<String, RegExp> translator})
: super(text: text) {
this.translator = translator ?? MaskedTextController.getDefaultTranslator();
this.addListener(() {
var previous = this._lastUpdatedText;
if (this.beforeChange(previous, this.text)) {
this.updateText(this.text);
this.afterChange(previous, this.text);
} else {
this.updateText(this._lastUpdatedText);
}
});
this.updateText(this.text);
}
String mask;
Map<String, RegExp> translator;
Function afterChange = (String previous, String next) {};
Function beforeChange = (String previous, String next) {
return true;
};
String _lastUpdatedText = '';
void updateText(String text) {
if(text != null){
this.text = this._applyMask(this.mask, text);
}
else {
this.text = '';
}
this._lastUpdatedText = this.text;
}
void updateMask(String mask, {bool moveCursorToEnd = true}) {
this.mask = mask;
this.updateText(this.text);
if (moveCursorToEnd) {
this.moveCursorToEnd();
}
}
void moveCursorToEnd() {
var text = this._lastUpdatedText;
this.selection = new TextSelection.fromPosition(
new TextPosition(offset: (text ?? '').length));
}
#override
void set text(String newText) {
if (super.text != newText) {
super.text = newText;
this.moveCursorToEnd();
}
}
static Map<String, RegExp> getDefaultTranslator() {
return {
'A': new RegExp(r'[A-Za-z]'),
'0': new RegExp(r'[0-9]'),
'#': new RegExp(r'[A-Za-z0-9]'),
'*': new RegExp(r'.*')
};
}
String _applyMask(String mask, String value) {
String result = '';
var maskCharIndex = 0;
var valueCharIndex = 0;
while (true) {
// if mask is ended, break.
if (maskCharIndex == mask.length) {
break;
}
// if value is ended, break.
if (valueCharIndex == value.length) {
break;
}
var maskChar = mask[maskCharIndex];
var valueChar = value[valueCharIndex];
// value equals mask, just set
if (maskChar == valueChar) {
result += maskChar;
valueCharIndex += 1;
maskCharIndex += 1;
continue;
}
// apply translator if match
if (this.translator.containsKey(maskChar)) {
if (this.translator[maskChar].hasMatch(valueChar)) {
result += valueChar;
maskCharIndex += 1;
}
valueCharIndex += 1;
continue;
}
// not masked value, fixed char on mask
result += maskChar;
maskCharIndex += 1;
continue;
}
return result;
}
}
Now call it in your main dart file
var maskedController = MaskedTextController(mask: '(000) 000-0000');
TextField(
controller: maskedController,
style: Styles.textNormalStyle,
maxLines: 1,
),
This solution work for your this specific Question and scenario.
you can achieve using following code.
String formattedPhoneNumber = "(" + phoneNumber.substring(0,3) + ") " +
phoneNumber.substring(3,6) + "-" +phoneNumber.substring(6,phoneNumber.length);
Ricardo pointed to a great library but his answer is half right. Besides the intl_phone_number_input you need to get libphonenumber_plugin installed as well.
intl_phone_number_input: ^0.7.0+2
libphonenumber_plugin:
The method getRegionInfoFromPhoneNumber "discovers" what country the number is from eg +55... it would interpret as it's from Brasil and proceed to format the phone number accordingly. You can also explicitly tell from where the phone number is from passing the country's acronym into the method eg. await PhoneNumber.getRegionInfoFromPhoneNumber(phone, "US"); It'll disregard a country code if it doesn't fit the number you're entering.
String phone = "+19795555555";
PhoneNumber number =
await PhoneNumber.getRegionInfoFromPhoneNumber(phone);
String formattedNumber = await PhoneNumberUtil.formatAsYouType(
number.phoneNumber!,
number.isoCode!,
);
print(formattedNumber); // -> prints: '+1 979-555-5555'
Also you can use: https://pub.dev/packages/intl_phone_number_input/example
String phoneNumber = '+234 500 500 5005';
PhoneNumber number = await PhoneNumber.getRegionInfoFromPhoneNumber(phoneNumber);
String parsableNumber = number.parseNumber();
`controller reference`.text = parsableNumber