iOS、Android处理Emoji表情(解决数据库不支持utf8mb4的问题)

Android代码

public class EmojiUtil {
     //编码
     public static String emojiConvert(String str) throws UnsupportedEncodingException {
        String patternString = "([\\x{10000}-\\x{10ffff}\ud800-\udfff])";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(
                                        sb,
                                        "[["
                                        + URLEncoder.encode(matcher.group(1),
                                        "UTF-8") + "]]");
            } catch(UnsupportedEncodingException e) {
                e.printStackTrace();
               throw e;
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
    
    //解码
    public static String emojiRecovery(String str) throws UnsupportedEncodingException {
        String patternString = "\\[\\[(.*?)\\]\\]";
        Pattern pattern = Pattern.compile(patternString);
        Matcher matcher = pattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            try {
                matcher.appendReplacement(sb,
                                        URLDecoder.decode(matcher.group(1), "UTF-8"));
            } catch(UnsupportedEncodingException e) {
                e.printStackTrace();
                throw e;
            }
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}

iOS代码

NSString+Message.m

//编码EMOJI表情字符串
- (NSString *)encodeEmojiString {
    NSMutableString *attributeString = [[NSMutableString alloc] initWithString:self];
    NSString *regex_emoji = @"[\\ud83c\\udc00-\\ud83c\\udfff]|[\\ud83d\\udc00-\\ud83d\\udfff]|[\\u2600-\\u27ff]";
    
    NSError *error = nil;
    NSRegularExpression *re = [NSRegularExpression
                               regularExpressionWithPattern:regex_emoji
                                                    options:NSRegularExpressionCaseInsensitive
                                                      error:&error];
    if (!re) {
        NSLog(@"[NSString toMessageString]: %@", [error localizedDescription]);
        return attributeString;
    }
    
    NSArray *resultArray = [re matchesInString:self options:0 range:NSMakeRange(0, self.length)];
    NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count];
    
    //根据匹配范围来用编码后的字符串进行相应的替换
    for(NSTextCheckingResult *match in resultArray) {
        //获取数组元素中得到range
        NSRange range = [match range];
        //获取原字符串中对应的值
        NSString *subStr = [self substringWithRange:range];
        //UTF8编码
        NSString *credentialName = [NSString emojiConvert:subStr];
        NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2];
        [imageDic setObject:credentialName forKey:@"image"];
        [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"];
        //把字典存入数组中
        [imageArray addObject:imageDic];
    }
    //从后往前替换,否则会引起位置问题
    for (int i = (int)imageArray.count -1; i >= 0; i--) {
        NSRange range;
        [imageArray[i][@"range"] getValue:&range];
        //进行替换
        [attributeString replaceCharactersInRange:range withString:imageArray[i][@"image"]];
    }
    return attributeString;
}

//解码EMOJI表情字符串
- (NSString *)decodeEmojiString {
    NSMutableString *attributeString = [[NSMutableString alloc] initWithString:self];
    NSString *regex_emoji = @"\\[\\[(.*?)\\]\\]";
    
    NSError *error = nil;
    NSRegularExpression *re = [NSRegularExpression
                               regularExpressionWithPattern:regex_emoji
                                                    options:NSRegularExpressionCaseInsensitive
                                                      error:&error];
    if (!re) {
        NSLog(@"[NSString toMessageString]: %@", [error localizedDescription]);
        return attributeString;
    }
    
    NSArray *resultArray = [re matchesInString:self options:0 range:NSMakeRange(0, self.length)];
    NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:resultArray.count];
    
    //根据匹配范围来用解码后的字符串进行相应的替换
    for(NSTextCheckingResult *match in resultArray) {
        //获取数组元素中得到range
        NSRange range = [match range];
        //获取原字符串中对应的值
        NSString *subStr = [self substringWithRange:range];
        //UTF8解码
        NSString *credentialName = [NSString emojiRecovery:subStr];
        NSMutableDictionary *imageDic = [NSMutableDictionary dictionaryWithCapacity:2];
        [imageDic setObject:credentialName forKey:@"image"];
        [imageDic setObject:[NSValue valueWithRange:range] forKey:@"range"];
        //把字典存入数组中
        [imageArray addObject:imageDic];
    }
    //从后往前替换,否则会引起位置问题
    for (int i = (int)imageArray.count -1; i >= 0; i--) {
        NSRange range;
        [imageArray[i][@"range"] getValue:&range];
        //进行替换
        [attributeString replaceCharactersInRange:range withString:imageArray[i][@"image"]];
    }
    return attributeString;
}

//对emoji转码
+ (NSString *)emojiConvert:(NSString *)obj {
    NSString *charactersToEscape = @"?!@#$^&%*+,:;='\"`<>()[]{}/\\| ";
    NSCharacterSet *allowedCharacters = [[NSCharacterSet
                                          characterSetWithCharactersInString:charactersToEscape] invertedSet];
    NSString *encodeStr = [obj stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacters];
    NSString *result = [NSString stringWithFormat:@"[[%@]]", encodeStr];
    return result;
}

//对emoji解码
+ (NSString *)emojiRecovery:(NSString *)obj {
    NSString *trimBeginStr = [obj stringByReplacingOccurrencesOfString:@"[[" withString:@""];
    NSString *trimEndStr = [trimBeginStr stringByReplacingOccurrencesOfString:@"]]" withString:@""];
    NSString *decodeStr = trimEndStr.stringByRemovingPercentEncoding;
    if (decodeStr == nil || [decodeStr isEqualToString:@""]) {
        return obj;
    } else {
        return decodeStr;
    }
}

参考文章

  • https://blog.csdn.net/zchangfeng/article/details/70142799
  • https://www.jianshu.com/p/eed8ef618af8

你可能感兴趣的:(iOS、Android处理Emoji表情(解决数据库不支持utf8mb4的问题))