Filter out a range of characters in dart - flutter

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>'));
}

Related

Extract template tags {{..}} from a string in 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

How to get list from docx file?

How to determine whether a list is bulleted or numbered? I use OpenXML
In general, what will be the list determines NumberingDefinitionsPart, I thought to find out the Numbering of a certain element, but this method did not work
I am processing the list in the recommended way, but I need to know which way it is
`public void ParagraphHandle(Elements.Paragraph paragraph, StringBuilder text)
{
var docPart = paragraph.DocumentPart;
var element = paragraph.Element;
var r = element.Descendants<Numbering>().ToArray();
var images = GetImages(docPart, element);
if (images.Count > 0)
{
foreach (var image in images)
{
if (image.Id != null)
{
string filePath = _saveResources.SaveImage(image);
_handler.ImageHandle(filePath, text);
}
}
return;
}
var paragraphProperties = element.GetFirstChild<ParagraphProperties>();
var numberingProperties = paragraphProperties?.GetFirstChild<NumberingProperties>();
if (numberingProperties != null)
{
var numberingId = numberingProperties.GetFirstChild<NumberingId>()?.Val?.Value;
if (numberingId != null && !paragraph.IsList)
{
text.AppendLine("<ul>");
paragraph.IsList = true;
paragraph.List = new List();
_htmlGenerator.GenerateList(paragraph, text);
}
else
{
_htmlGenerator.GenerateList(paragraph, text);
}
}
else
{
if (paragraph.IsList)
{
text.AppendLine("</ul>");
paragraph.IsList = false;
}
_handler.ParagraphHandle(element, text);
}
}`

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.

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

Replace bookmark contents in Word using OpenXml

I can't find any working code examples for replacing bookmark contents. The code should be able to handle both the case replace empty bookmark and replace bookmark with preexisting content.
For example: If I have this text in a Word document:
"Between the following periods comes Bookmark1.. Between next periods comes Bookmark2.."
and I want to insert the text "BM1" between the first periods, and "BM2" between the next.
After the first replacement run, the replacements are inserted correctly.
But after the next replacement run, all of the text on the line after Bookmark1 gets deleted, and then the replacement for Bookmark2 gets inserted.
This is my c# code:
var doc = WordprocessingDocument.Open(#"file.docx", true);
public static Dictionary<string, wd.BookmarkStart> FindAllBookmarksInWordFile(WordprocessingDocument file)
{
var bookmarkMap = new Dictionary<String, wd.BookmarkStart>();
foreach (var headerPart in file.MainDocumentPart.HeaderParts)
{
foreach (var bookmarkStart in headerPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
}
foreach (var bookmarkStart in file.MainDocumentPart.RootElement.Descendants<wd.BookmarkStart>())
{
if (!bookmarkStart.Name.ToString().StartsWith("_"))
bookmarkMap[bookmarkStart.Name] = bookmarkStart;
}
return bookmarkMap;
}
/*extension methods*/
public static bool IsEndBookmark(this OpenXmlElement element, BookmarkStart startBookmark)
{
return IsEndBookmark(element as BookmarkEnd, startBookmark);
}
public static bool IsEndBookmark(this BookmarkEnd endBookmark, BookmarkStart startBookmark)
{
if (endBookmark == null)
return false;
return endBookmark.Id.Value == startBookmark.Id.Value;
}
/* end of extension methods */
public static void SetText(BookmarkStart bookmark, string value)
{
RemoveAllTexts(bookmark);
bookmark.Parent.InsertAfter(new Run(new Text(value)), bookmark);
}
private static void RemoveAllTexts(BookmarkStart bookmark)
{
if (bookmark.ColumnFirst != null) return;
var nextSibling = bookmark.NextSibling();
while (nextSibling != null)
{
if (nextSibling.IsEndBookmark(bookmark) || nextSibling.GetType() == typeof(BookmarkStart))
break;
foreach (var item in nextSibling.Descendants<Text>())
{
item.Remove();
}
nextSibling = nextSibling.NextSibling();
}
}
I have looked around a long time for a general solution.
Any help is appreciated! -Victor
Maybe this can help you
first:delete bookmarkContent
second:find bookMark => insert value
public static void InsertTest1(WordprocessingDocument doc, string bookMark, string txt)
{
try
{
RemoveBookMarkContent(doc, bookMark);
MainDocumentPart mainPart = doc.MainDocumentPart;
BookmarkStart bmStart = findBookMarkStart(doc, bookMark);
if (bmStart == null)
{
return;
}
Run run = new Run(new Text(txt));
bmStart.Parent.InsertAfter<Run>(run, bmStart);
}
catch (Exception c)
{
//not Exception
}
}
public static void RemoveBookMarkContent(WordprocessingDocument doc, string bmName)
{
BookmarkStart bmStart = findBookMarkStart(doc, bmName);
BookmarkEnd bmEnd = findBookMarkEnd(doc, bmStart.Id);
while (true)
{
var run = bmStart.NextSibling();
if (run == null)
{
break;
}
if (run is BookmarkEnd && (BookmarkEnd)run == bmEnd)
{
break;
}
run.Remove();
}
}
private static BookmarkStart findBookMarkStart(WordprocessingDocument doc, string bmName)
{
foreach (var footer in doc.MainDocumentPart.FooterParts)
{
foreach (var inst in footer.Footer.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var header in doc.MainDocumentPart.HeaderParts)
{
foreach (var inst in header.Header.Descendants<BookmarkStart>())
{
if (inst.Name == bmName)
{
return inst;
}
}
}
foreach (var inst in doc.MainDocumentPart.RootElement.Descendants<BookmarkStart>())
{
if (inst is BookmarkStart)
{
if (inst.Name == bmName)
{
return inst;
}
}
}
return null;
}
This code works but not when the bookmark is placed within a field/formtext (a gray box).
private static void SetNewContents(wd.BookmarkStart bookmarkStart, string text)
{
if (bookmarkStart.ColumnFirst != null) return;
var itemsToRemove = new List<OpenXmlElement>();
var nextSibling = bookmarkStart.NextSibling();
while (nextSibling != null)
{
if (IsEndBookmark(nextSibling, bookmarkStart))
break;
if (nextSibling is wd.Run)
itemsToRemove.Add(nextSibling);
nextSibling = nextSibling.NextSibling();
}
foreach (var item in itemsToRemove)
{
item.RemoveAllChildren();
item.Remove();
}
bookmarkStart.Parent.InsertAfter(new wd.Run(new wd.Text(text)), bookmarkStart);
}