Accurately find or remove emojis from a blob of text.
demoji
requires an initial data download from the Unicode Consortium's emoji code repository.
On first use of the package, call download_codes()
:
>>> import demoji
>>> demoji.download_codes()
Downloading emoji data ...
... OK (Got response in 0.14 seconds)
Writing emoji data to /Users/brad/.demoji/codes.json ...
... OK
This will store the Unicode hex-notated symbols at ~/.demoji/codes.json
for future use.
demoji
exports several text-related functions for find-and-replace functionality with emojis:
>>> tweet = """\
... #startspreadingthenews yankees win great start by ๐
๐พ going 5strong innings with 5kโs๐ฅ ๐
... solo homerun ๐๐ with 2 solo homeruns and๐น 3run homerunโฆ ๐คก ๐ฃ๐ผ ๐จ๐ฝโโ๏ธ with rbiโs โฆ ๐ฅ๐ฅ
... ๐ฒ๐ฝ and ๐ณ๐ฎ to close the game๐ฅ๐ฅ!!!โฆ.
... WHAT A GAME!!..
... """
>>> demoji.findall(tweet)
{
"๐ฅ": "fire",
"๐": "volcano",
"๐จ๐ฝ\u200dโ๏ธ": "man judge: medium skin tone",
"๐
๐พ": "Santa Claus: medium-dark skin tone",
"๐ฒ๐ฝ": "flag: Mexico",
"๐น": "ogre",
"๐คก": "clown face",
"๐ณ๐ฎ": "flag: Nicaragua",
"๐ฃ๐ผ": "person rowing boat: medium-light skin tone",
"๐": "ox",
}
See below for function API.
The reason that demoji
requires a download rather than coming pre-packaged with Unicode emoji data is that the emoji list itself is frequently updated and changed. You are free to periodically update the local cache by calling demoji.download_codes()
every so often.
To pull your last-downloaded date, you can use the last_downloaded_timestamp()
helper:
>>> demoji.last_downloaded_timestamp()
datetime.datetime(2019, 2, 9, 7, 42, 24, 433776, tzinfo=<demoji.UTC object at 0x101b9ecf8>)
The result will be None
if codes have not previously been downloaded.
Note: Text
refers to typing.Text
, an alias for str
in Python 3 or unicode
in Python 2.
download_codes() -> None
Download emoji data to ~/.demoji/codes.json. Required at first module usage, and can be used to periodically update data.
findall(string: Text) -> Dict[Text, Text]
Find emojis within string
. Return a mapping of {emoji: description}
.
findall_list(string: Text, desc: bool = True) -> List[Text]
Find emojis within string
. Return a list (with possible duplicates).
If desc
is True, the list contains description codes. If desc
is False, the list contains emojis.
replace(string: Text, repl: Text = "") -> Text
Replace emojis in string
with repl
.
replace_with_desc(string: Text, sep: Text = ":") -> Text
Replace emojis in string
with their description codes. The codes are surrounded by sep
.
last_downloaded_timestamp() -> Optional[datetime.datetime]
Show the timestamp of last download from download_codes()
.
Numerous emojis that look like single Unicode characters are actually multi-character sequences. Examples:
- The keycap 2๏ธโฃ is actually 3 characters, U+0032 (the ASCII digit 2), U+FE0F (variation selector), and U+20E3 (combining enclosing keycap).
- The flag of Scotland 7 component characters,
b'\\U0001f3f4\\U000e0067\\U000e0062\\U000e0073\\U000e0063\\U000e0074\\U000e007f'
in full esaped notation.
(You can see any of these through s.encode("unicode-escape")
.)
demoji
is careful to handle this and should find the full sequences rather than their incomplete subcomponents.
The way it does this it to sort emoji codes by their length, and then compile a concatenated regular expression that will greedily search for longer emojis first, falling back to shorter ones if not found. This is not by any means a super-optimized way of searching as it has O(N2) properties, but the focus is on accuracy and completeness.
>>> from pprint import pprint
>>> seq = """\
... I bet you didn't know that ๐, ๐โโ๏ธ, and ๐โโ๏ธ are three different emojis.
... """
>>> pprint(seq.encode('unicode-escape')) # Python 3
(b"I bet you didn't know that \\U0001f64b, \\U0001f64b\\u200d\\u2642\\ufe0f,"
b' and \\U0001f64b\\u200d\\u2640\\ufe0f are three different emojis.\\n')