Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Remove Emoji in NSString
// XCode 4.2.1
@implementation NSString(EmojiExtension)
- (NSString*)removeEmoji {
__block NSMutableString* temp = [NSMutableString string];
[self enumerateSubstringsInRange: NSMakeRange(0, [self length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:
^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
const unichar hs = [substring characterAtIndex: 0];
// surrogate pair
if (0xd800 <= hs && hs <= 0xdbff) {
const unichar ls = [substring characterAtIndex: 1];
const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
[temp appendString: (0x1d000 <= uc && uc <= 0x1f77f)? @"": substring]; // U+1D000-1F77F
// non surrogate
} else {
[temp appendString: (0x2100 <= hs && hs <= 0x26ff)? @"": substring]; // U+2100-26FF
}
}];
return temp;
}
@end
@DHowett

This comment has been minimized.

Copy link

commented Aug 1, 2014

Why muck about with surrogate pairs and blocks (and function call overhead) if you don't have to?

#include <unicode/utf8.h>
@implementation NSString (EmojiExtension)
- (NSString *)stringByRemovingEmoji {
    NSData *d = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:NO];
    if(!d) return nil;
    const char *buf = d.bytes;
    unsigned int len = [d length];
    char *s = (char *)malloc(len);
    unsigned int ii = 0, oi = 0; // in index, out index
    UChar32 uc;
    while (ii < len) {
        U8_NEXT_UNSAFE(buf, ii, uc);
        if(0x2100 <= uc && uc <= 0x26ff) continue;
        if(0x1d000 <= uc && uc <= 0x1f77f) continue;
        U8_APPEND_UNSAFE(s, oi, uc);
    }
    return [[[NSString alloc] initWithBytesNoCopy:s length:oi encoding:NSUTF8StringEncoding freeWhenDone:YES] autorelease];
}
@end

(Gist'd here)

@nschum

This comment has been minimized.

Copy link

commented May 1, 2015

Swift version:

extension Character {
    func isEmoji() -> Bool {
        return Character(UnicodeScalar(0x1d000)) <= self && self <= Character(UnicodeScalar(0x1f77f))
            || Character(UnicodeScalar(0x2100)) <= self && self <= Character(UnicodeScalar(0x26ff))
    }
}

extension String {
    func stringByRemovingEmoji() -> String {
        return String(filter(self, {c in !c.isEmoji()}))
    }
}
@deya-eldeen

This comment has been minimized.

Copy link

commented Jun 19, 2016

thanks nschum, but this is not working for swift 2.2, there is a problem in
c.isEmoji()

@crazypepper

This comment has been minimized.

Copy link

commented Jul 12, 2016

For Swift 2.2:

extension Character {
    func isEmoji() -> Bool {
        return Character(UnicodeScalar(0x1d000)) <= self && self <= Character(UnicodeScalar(0x1f77f))
            || Character(UnicodeScalar(0x2100)) <= self && self <= Character(UnicodeScalar(0x26ff))
    }
}

extension String {
    func stringByRemovingEmoji() -> String {
        return String(self.characters.filter{!$0.isEmoji()})
    }
}
@foffer

This comment has been minimized.

Copy link

commented Dec 9, 2016

Swift 3.0

extension Character {
    fileprivate func isEmoji() -> Bool {
        return Character(UnicodeScalar(UInt32(0x1d000))!) <= self && self <= Character(UnicodeScalar(UInt32(0x1f77f))!) 
            || Character(UnicodeScalar(UInt32(0x2100))!) <= self && self <= Character(UnicodeScalar(UInt32(0x26ff))!)
    }
}

extension String {
    func stringByRemovingEmoji() -> String {
        return String(self.characters.filter { !$0.isEmoji() })
    }
}
@deya-eldeen

This comment has been minimized.

Copy link

commented May 3, 2017

in XCode 8.3.2 ...

func stringByRemovingEmoji() -> String {
    return String(self.characters.filter { !$0.isEmoji() })
}

no longer works.

@maira786

This comment has been minimized.

Copy link

commented Nov 26, 2017

Swift 4.0

extension Character {
    fileprivate func isEmoji() -> Bool {
        return Character(UnicodeScalar(UInt32(0x1d000))!) <= self && self <= Character(UnicodeScalar(UInt32(0x1f77f))!) 
            || Character(UnicodeScalar(UInt32(0x2100))!) <= self && self <= Character(UnicodeScalar(UInt32(0x26ff))!)
    }
}

extension String {
    func stringByRemovingEmoji() -> String {
        return String(self.filter { !$0.isEmoji() })
    }
}
@simon9211

This comment has been minimized.

Copy link

commented May 2, 2018

the emoj of heart ❤️ does not work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.