4

Basically what I want to do is to match only strings that contain emojis and no other characters. It could have one or many emojis as long as there are no other characters.

I know there has been questions like it in the past but none of them supports all emojis.

I'm using the following to detect emojis but am unsure how to exclude other characters from it.

  const regex = /\p{Extended_Pictographic}/ug
  return regex.test(mystr);

These are my test cases and the expected results:

    d‍❤️‍‍f -> false
    t -> false
    3 -> false
     -> true
    ❤️ -> true
     -> true
    ‍♂️ -> true
     -> true
     -> true

You may test the result here: https://regex101.com/r/krwZ7W/1

Vahid Amiri
  • 10,769
  • 13
  • 68
  • 113
  • 2
    `/^\p{Extended_Pictographic}+$/` should only match those characters. But it seems some of your characters are not in that group: https://regex101.com/r/Ya2C2C/1 – Nick Sep 07 '22 at 07:06
  • @Nick If you use the exact regex I provided, you can see that all of them match, but I just want to match those groups without any characters beside/in between them. – Vahid Amiri Sep 07 '22 at 07:15
  • 2
    The rules for what sequences of code points count as an emoji are fairly complicated. I once wrote an RE to match every case (except for things like validating country codes), but it's in perl and won't easily convert to JavaScript. (It's also probably 20+ lines long iirc). – Shawn Sep 07 '22 at 07:15
  • 2
    @VahidAmiri yes - but if you look at my demo and remove the `^` and `$` from the regex you'll see that not all the emojis match that group – Nick Sep 07 '22 at 07:18
  • 3
    @VahidAmiri Emojis are not only present in the `Extended_pictographic` group. They are spread in [a big amount of groups](https://en.wikipedia.org/wiki/Emoji#In_Unicode). There is also a group `\p{Emoji}` that doesn't even cover all of em. – Christopher Sep 07 '22 at 07:38
  • 1
    Does this answer your question? "[Check if string contains only emojis - Javascript](/q/56504602/90527)", "[Detecting *all* emojis](/q/46905176/90527)" – outis Sep 07 '22 at 11:01
  • @outis no it's obviously not good enough as it is mentioned in the comments – Vahid Amiri Sep 07 '22 at 12:55
  • 1
    Based on the comment from @outis, [here](https://jsfiddle.net/nst93y7j/) is a small fiddle which makes use of the regex and information from [that answer](https://stackoverflow.com/a/68463901/10304804). And the [reference](https://www.unicode.org/reports/tr51/#EBNF_and_Regex). – Christopher Sep 07 '22 at 14:16
  • @Christopher I edited my answer to include your solution as it seems to work better than my own. – Vahid Amiri Sep 07 '22 at 21:32

1 Answers1

1

Updated answer: The following is based on the below comment from Christopher (which they mention is itself based on a comment from outis).

Original comment from Christopher:

Based on the comment from @outis, here is a small fiddle which makes use of the regex and information from that answer. And the reference.

Feels like at the moment it is THE ultimate solution.

isEmojiOnly(str) {
  const stringToTest = str.replace(/ /g,'');
  const emojiRegex = /^(?:(?:\p{RI}\p{RI}|\p{Emoji}(?:\p{Emoji_Modifier}|\u{FE0F}\u{20E3}?|[\u{E0020}-\u{E007E}]+\u{E007F})?(?:\u{200D}\p{Emoji}(?:\p{Emoji_Modifier}|\u{FE0F}\u{20E3}?|[\u{E0020}-\u{E007E}]+\u{E007F})?)*)|[\u{1f900}-\u{1f9ff}\u{2600}-\u{26ff}\u{2700}-\u{27bf}])+$/u;
  return emojiRegex.test(stringToTest) && Number.isNaN(Number(stringToTest));
}

Old Answer: The following fails for number emojis and flags and maybe more.

This is what I came up with, not sure how it holds up against all test cases but it should be decent enough to be usable. This function will test the input to see if it ONLY contains emojis.

function isEmojiOnly(str) {
  // remove all white spaces from the input
  const stringToTest = str.replace(/ /g,'');
  const regexForEmojis = /\p{Extended_Pictographic}/ug;
  const regexForAlphaNums = /[\p{L}\p{N}]+/ug;

  // check to see if the string contains emojis
  if (regexForEmojis.test(stringToTest)) {
    // check to see if it contains any alphanumerics
    if (regexForAlphaNums.test(stringToTest)) {
      return false;
    }
    return true;
  }

  return false;
}
Vahid Amiri
  • 10,769
  • 13
  • 68
  • 113