36

Is there a way to split a string by some symbol but only at first occurrence?

Example: date: '2019:04:01' should be split into date and '2019:04:01'
It could also look like this date:'2019:04:01' or this date : '2019:04:01' and should still be split into date and '2019:04:01'

string.split(':');

I tried using the split() method. But it doesn't have a limit attribute or something like that.

2
  • 2
    Use RegExp in split. Commented Feb 25, 2020 at 20:38
  • 1
    How does this work? Commented Feb 25, 2020 at 20:53

10 Answers 10

48

You were never going to be able to do all of that, including trimming whitespace, with the split command. You will have to do it yourself. Here's one way:

String s = "date   :   '2019:04:01'";
int idx = s.indexOf(":");
List parts = [s.substring(0,idx).trim(), s.substring(idx+1).trim()];
Sign up to request clarification or add additional context in comments.

Comments

38

You can split the string, skip the first item of the list created and re-join them to a string.

In your case it would be something like:

var str = "date: '2019:04:01'";
var parts = str.split(':');
var prefix = parts[0].trim();                 // prefix: "date"
var date = parts.sublist(1).join(':').trim(); // date: "'2019:04:01'"

The trim methods remove any unneccessary whitespaces around the first colon.

3 Comments

I also thought about that. I hoped that there would be a cleaner solution.
Cleaner than that? Put it into an extension function called splitFirst() and you'll get it as clean as it gets. :-)
I'm don't really know how truly work dart but I think that this solution is way more complex that it should be, it read the whole string and create multiple substring while it should only read until it encounter the pattern and create only 2 string. I think the best solution is the solution of @WaltPurvis
11

Just use the split method on the string. It accepts a delimiter/separator/pattern to split the text by. It returns a list of values separated by the provided delimiter/separator/pattern.

Usage:

const str = 'date: 2019:04:01';
final values = string.split(': '); // Notice the whitespace after colon

Output:

enter image description here

2 Comments

Thank you for your answer. But it's possible, that there is no whitespace after the first :
In that case you can simple check if the string contains a whitespace or not. If it contains then use my solution else use string.split(":'")
5

Inspired by python, I've wrote this utility function to support string split with an optionally maximum number of splits. Usage:

split("a=b=c", "="); // ["a", "b", "c"]
split("a=b=c", "=", max: 1); // ["a", "b=c"]
split("",""); // [""] (edge case where separator is empty)
split("a=", "="); // ["a", ""]
split("=", "="); // ["", ""]
split("date: '2019:04:01'", ":", max: 1) // ["date", " '2019:04:01'"] (as asked in question)

Define this function in your code:

List<String> split(String string, String separator, {int max = 0}) {
  var result = List<String>();

  if (separator.isEmpty) {
    result.add(string);
    return result;
  }

  while (true) {
    var index = string.indexOf(separator, 0);
    if (index == -1 || (max > 0 && result.length >= max)) {
      result.add(string);
      break;
    }

    result.add(string.substring(0, index));
    string = string.substring(index + separator.length);
  }

  return result;
}

Online demo: https://dartpad.dev/e9a5a8a5ff803092c76a26d6721bfaf4

Comments

4

I found that very simple by removing the first item and "join" the rest of the List

String date = "date:'2019:04:01'";
List<String> dateParts = date.split(":");
List<String> wantedParts = [dateParts.removeAt(0),dateParts.join(":")];

Comments

3

You can use extensions and use this one for separating text for the RichText/TextSpan use cases:

extension StringExtension on String {
 List<String> controlledSplit(
  String separator, {
  int max = 1,
  bool includeSeparator = false,
  }) {
   String string = this;
   List<String> result = [];

   if (separator.isEmpty) {
     result.add(string);
     return result;
   }

   while (true) {
     var index = string.indexOf(separator, 0);
     print(index);
     if (index == -1 || (max > 0 && result.length >= max)) {
       result.add(string);
       break;
     }

     result.add(string.substring(0, index));
     if (includeSeparator) {
       result.add(separator);
     }
     string = string.substring(index + separator.length);
   }

   return result;
 }
}

Then you can just reference this as a method for any string through that extension:

void main() {
 String mainString = 'Here was john and john was here';
 print(mainString.controlledSplit('john', max:1, includeSeparator:true));
}

Comments

2

Use RegExp

string.split(RegExp(r":\s*(?=')"));
  1. Note the use of a raw string (a string prefixed with r)
  2. \s* matches zero or more whitespace character
  3. (?=') matches ' without including itself

Comments

0

Just convert list to string and search

  productModel.tagsList.toString().contains(filterText.toLowerCase())

Comments

0

Just write an extension on Strings

extension StringExtension on String {
(String, String) splitFirst({String separator = ":"}) {
 int separatorPosition = indexOf(separator);
 if (separatorPosition == -1) {
  return (this, "");
 }
 return (substring(0, separatorPosition), substring(separatorPosition + separator.length));
}}

And use it like this

final (firstPart, secondPart) = yourString.splitFirst();

Comments

0
void main() {
   var str = 'date: 2019:04:01';
   print(str.split(" ").last.trim()); //2019:04:01
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.