2

I want to split a string of emojis into each emoji. so how can I do this in dart language?

void main() {
  print('GoodJob'.split("")); // output: [G, o, o, d, J, o, b]
    print(''.split(""));  // output: [�, �, �, �, �, �] but expected: ['','','']
}
MendelG
  • 14,885
  • 4
  • 25
  • 52
Pankaj
  • 21
  • 1
  • 5

3 Answers3

4

Docs from TextField recommends to use characters package to work with emoji in dart.

Docs describe as follows,

It's important to always use characters when dealing with user input text that may contain complex characters. This will ensure that extended grapheme clusters and surrogate pairs are treated as single characters, as they appear to the user.

For example, when finding the length of some user input, use string.characters.length. Do NOT use string.length or even string.runes.length. For the complex character "‍‍", this appears to the user as a single character, and string.characters.length intuitively returns 1. On the other hand, string.length returns 8, and string.runes.length returns 5!

import 'package:characters/characters.dart';

void main() {
  print(''.characters.split("".characters));
}

outputs

(, , )
Anas
  • 1,013
  • 1
  • 6
  • 20
  • Hello, can you point to the official docs recommending the use of `characters`? – Chuck Batson Jan 08 '23 at 16:55
  • 1
    Its from Flutter [Textfield[(https://api.flutter.dev/flutter/material/TextField-class.html) docs recommends and provides better example explaining why to use characters package. Scroll down to `Handling emojis and other complex characters` section. – Anas Jan 08 '23 at 16:58
  • 1
    Excellent. I humbly suggest that you add the link, as well as quote that section, in your answer. There's some material information that's very relevant to the answer, as well as to people who see this later who are evaluating what approach to use -- particularly the limitations of `String.runes` when dealing with complex emojis. – Chuck Batson Jan 08 '23 at 18:24
1

You can match all the emojis using regex, and then add them to a list:

List<String> splitEmoji(String text) {
  final List<String> out = [];
  final pattern = RegExp(
      r'(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])');

  final matches = pattern.allMatches(text);
  for (final match in matches) {
    out.add(match.group(0)!);
  }
  return out;
}

Regex credit

Usage:

print(splitEmoji('')); // Output: [, , ]
MendelG
  • 14,885
  • 4
  • 25
  • 52
1

You can use the runes property of String.

void main() {
  final String emojis = '';
  final Runes codePoints = emojis.runes;
  for (final codePoint in codePoints) {
    print(String.fromCharCode(codePoint));
  }
}
Omar Sahl
  • 76
  • 5