3

I'm using EmojiMart for my parser.

I've seen this related question but it seem to be different from mine.

So I need to return the emoji names or :code: for them to be able to decode it.

So example I have this text:

:+1::skin-tone-6::man-pouting:Hello world:skin-tone- 
6:lalalalla:person_with_pouting_face: :poop::skin-tone-11: mamamia 
:smile: :skin-tone-6:

It should match the whole :+1::skin-tone-6: and not a separate :+1:, :skin-tone-6:: - only if there’s no space between them. (notice the space between :smile: and :skin-tone-6: )

Conditions:

It should only match the :code::skintone: if skintone is 2-6

If I do str.split(regex) this is my expected result (array):

- :+1::skin-tone-6:
- :man-pouting:
- Hello world
- :skin-tone-6:
- lalalalla
- :person_with_pouting_face: 
- :poop:
- :skin-tone-11: 
-  mamamia 
- :smile: 
- :skin-tone-6:
I am L
  • 4,288
  • 6
  • 32
  • 49

1 Answers1

1

You may use String#split() with the

/(:[^\s:]+(?:::skin-tone-[2-6])?:)/

regex. See the regex demo.

Details

  • : - a colon
  • [^\s:]+ - 1+ chars other than whitespace and :
  • (?:::skin-tone-[2-6])? - an optional sequence of
    • ::skin-tone- - a literal substring
    • [2-6] - a digit from 2 to 6
  • : - a colon.

JS demo:

var s = ":+1::skin-tone-6::man-pouting:Hello world:skin-tone-6:lalalalla:person_with_pouting_face: :poop::skin-tone-11: mamamia :smile: :skin-tone-6:";
var reg = /(:[^\s:]+(?:::skin-tone-[2-6])?:)/;
console.log(s.split(reg).filter(x => x.trim().length !=0 ));

The .filter(x => x.trim().length !=0 ) removes all blank items from the resulting array. For ES5 and older, use .filter(function(x) { return x.trim().length != 0; }).

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thank you good sir. I wonder if I can do it on `str.replace(regex, callback)` too. right now I'm doing `str.split(regex).filter(Boolean).map(emoji => myfunction).join('')` Just to mimic what replace does. But I think replace is much faster. – I am L Jul 13 '18 at 12:49
  • @IamL Do you need to replace them with something else? Yes, something like `.replace(reg, function(match) { return myfunction(match); })` will work. – Wiktor Stribiżew Jul 13 '18 at 12:55
  • yes, however replace will only replace the one with `:+1::skin-tone-6:`. It doesn't "match" other `:code:` (without skintone). I guess I have to use split instead? – I am L Jul 13 '18 at 13:01
  • @IamL What is the expected result for the input string? – Wiktor Stribiżew Jul 13 '18 at 13:07
  • The goal here is to replace all `:code:` with a corresponding emoji. Before I have something like: `str.replace(/(:[+\-\d\w]+:)/gm, match => getEmoji(match))` However my problem is that some `:code:` looks like `:code::skintone:` (which is what this question is for). with my old regex it returns all `:code:` but since I changed it to your answer, it only replaces the `:code::skintone:` ones and not the `:code:` only. But I guess that is expected? – I am L Jul 13 '18 at 13:13
  • @IamL Really, sorry, I don't get it. See http://jsfiddle.net/ew8akcnd/4/. Is it something like that? – Wiktor Stribiżew Jul 13 '18 at 13:19
  • No worries, you've done enough, But Yeah something like that and the `:poop:` should be replaced as `000` instead of only replacing the `:+1::skin-tone-6:`. – I am L Jul 13 '18 at 13:28
  • 2
    @IamL :) Forgot about the global modifier, [updated fiddle](http://jsfiddle.net/Larmgpqd/). When you use a regex in a `split()` method, the default behavior is to find all matches to split with. In `.replace`, it should be defined explicitly. – Wiktor Stribiżew Jul 13 '18 at 13:29
  • ^ same, perfect for matching back to back colon represented emojis – Steve Pascoe Oct 05 '18 at 07:02