emoji
Find, count, extract and strip emoji in text, with flags, skin tones and joined sequences each counted as one.
import "std:emoji"Emoji are trickier than they look. A flag is two code points, a thumbs up with a skin tone is two, and a family is five (three people joined by two invisible joiners). Counting them with .len or splitting a string by character gets this wrong. std:emoji knows the rules: each of those is one emoji.
Detecting and counting#
import "std:emoji"
string message = "Great work ๐๐ฝ see you in ๐ฌ๐ง"
log emoji.hasEmoji(message)
log emoji.hasEmoji("no emoji here")
log emoji.count(message)The text's .len counts every code point that went into the emoji:
import "std:emoji"
string family = "๐จโ๐ฉโ๐ง"
log emoji.count(family)
log family.lenExtracting#
extract returns each emoji in order, whole:
import "std:emoji"
string post = "Hi ๐๐ฝ from ๐ฌ๐ง and ๐จโ๐ฉโ๐ง, keycap 1๏ธโฃ and ๐"
log emoji.extract(post)
log emoji.extract("none")Counting how often each one appears is then a few lines of map:
import "std:emoji"
string chat = "๐ ๐ ๐ ๐ ๐ ๐"
string[int] tally = {}
for e in emoji.extract(chat) (
tally[e] = (tally[e] ?? 0) + 1
)
for e in tally.getKeys().toSorted() (
log e tally[e]
)Removing and replacing#
remove deletes every emoji. replace swaps each one for text:
import "std:emoji"
string text = "Launch day ๐ !"
log emoji.remove(text)
log emoji.replace(text, "[emoji]")
log emoji.replace("a๐b๐c", "")Removing leaves the spaces around the emoji, so tidy up afterwards with .trim().
Asking what a string is#
import "std:emoji"
log emoji.isFlag("๐ฌ๐ง") emoji.isFlag("๐")
log emoji.isOnlyEmoji("๐๐") emoji.isOnlyEmoji("a๐")
log emoji.isZWJSequence("๐จโ๐ฉโ๐ง") emoji.isZWJSequence("๐")A ZWJ sequence is several emoji joined by a zero-width joiner into one picture, such as a family or a profession.
Skin tones#
hasSkinTone tells whether a skin-tone modifier is present, and findSkinTone names the first one: "light", "medium-light", "medium", "medium-dark" or "dark", or null when there is none:
import "std:emoji"
log emoji.hasSkinTone("๐๐ฝ")
log emoji.findSkinTone("๐๐ฝ")
log emoji.findSkinTone("๐") ?? "none"Validating a reaction#
A reaction field should hold exactly one emoji and nothing else. isValidReaction checks that:
import "std:emoji"
string[] tries = ["๐", "๐๐", "a", "๐ฌ๐ง", "๐จโ๐ฉโ๐ง"]
for t in tries (
log t emoji.isValidReaction(t)
)What does emoji.count("๐ฌ๐ง") return?
Clean a status
Finish clean so it removes every emoji from a status and trims the spaces they leave behind.
Launch Party plain
API reference#
14 members, generated from the std:emoji source of OSL 9.3.0.
Functions
emoji.count(string text) intcount returns how many emoji text contains. A flag, keycap, toned emoji or ZWJ sequence such as a family counts as one.
emoji.extract(string text) string[]extract returns every emoji in text in order, each flag, keycap, toned emoji or ZWJ sequence as one string; [] when there are none.
emoji.findSkinTone(string text) string?findSkinTone returns the name of the first skin tone in text: "light", "medium-light", "medium", "medium-dark" or "dark", or null when text has no skin-tone modifier.
emoji.hasEmoji(string text) booleanhasEmoji reports whether text contains at least one emoji.
emoji.hasSkinTone(string text) booleanhasSkinTone reports whether text contains a skin-tone modifier.
emoji.isEmoji(any text) booleanDeprecated. Deprecated: use emoji.hasEmoji(text) instead.
isEmoji reports whether text contains at least one emoji.
emoji.isFlag(string text) booleanisFlag reports whether text is exactly one flag: a pair of regional indicator symbols (the pair is two code points, eight bytes) or a tag sequence flag such as England's.
emoji.isOnlyEmoji(string text) booleanisOnlyEmoji reports whether text is one or more emoji with nothing else, not even spaces. An empty string is not.
emoji.isValidReaction(string text) booleanisValidReaction reports whether text can be used as a reaction: exactly one emoji, or an originChats custom reaction "originChats:<emoji>//" wrapping exactly one emoji.
emoji.isZWJSequence(string text) booleanisZWJSequence reports whether text contains a zero-width joiner (U+200D), which joins emoji such as a family or a profession into one.
emoji.onlyEmoji(any text) booleanDeprecated. Deprecated: use emoji.isOnlyEmoji(text) instead.
onlyEmoji reports whether text is one or more emoji and nothing else.
emoji.remove(string text) stringremove returns text with every emoji removed.
emoji.replace(string text, string replacement) stringreplace returns text with each emoji replaced by replacement, taken literally: "$1" or "${x}" in it is not expanded.
emoji.skinTone(any text) stringDeprecated. Deprecated: use emoji.findSkinTone(text) instead, which returns null when there is no skin tone.
skinTone returns the name of the first skin tone in text, or "none".