Search code examples
rregexemojiutf-16

How can I match emoji with an R regex?


I want to determine which elements of my vector contain emoji:

x = c('😂', 'no', '🍹', '😀', 'no', '😛', '䨺', '감사')
x
# [1] "\U0001f602" "no"         "\U0001f379" "\U0001f600" "no"         "\U0001f61b" "䨺"         "감사"

Related posts only cover other languages, and because mostly they refer to specialized libraries, I couldn't figure out a way to translate to R:

The second looked very promising, but alas (not fixed by supplying perl = TRUE):

x[grepl('[\u{1F600}-\u{1F6FF}]', x)]

Error: invalid \u{xxxx} sequence (line 1)

Similar issues come about from other questions. How can we match emoji in R?


Solution

  • I am converting the encoding to UTF-8 to compare the UTF-8 value of emoji's value with all the emoji's value in remoji library which is in UTF-8. I am using the stringr library to find the position of emoji's in the vector. One is free to use grep or any other function.

    1st Method:

    library(stringr)
    xvect = c('😂', 'no', '🍹', '😀', 'no', '😛')
    
    Encoding(xvect) <- "UTF-8"
    
    which(str_detect(xvect,"[^[:ascii:]]"))
    # [1] 1 3 4 6
    

    Here 1,3,4 and 6 are emoji's character in this case.

    Edited :

    2nd Method: Install a GitHub package called remoji. Since we have already converted the emoji items into UTF-8. we can now compare the UTF-8 values of all the emoji's present in the emoji library. Use trimws to remove the whitespaces

    library(remoji) # remotes::install_github("richfitz/remoji")
    emj <- emoji(list_emoji(), TRUE)
    which(xvect %in% trimws(emj))
    # [1] 1 3 4 6
    

    Both of the above methods are not full proof and first method assumes that there are no any ascii characters other than emojis in the vector and second method relies on the library information of remoji. In case where the a certain emoji information is not present in the library, the last command may yield a FALSE instead of TRUE.

    Final Edit:

    As per the discussion amongst OP(@MichaelChirico) and @SymbolixAU. Thanks to both of them it seems the problem with small typo of capital U. The new regex is xvect[grepl('[\U{1F300}-\U{1F6FF}]', xvect)] . The range in the character class is taken from F300 to F6FF. One can off course change this range to a new range in cases where an emoji lies outside this range. This may not be the complete list and over the period of time these ranges may keep increasing/changing.