2016-09-02 2 views
0

Я видел предыдущие ответы на этот вопрос, но ни один из них не является последним, и ни один из них не работает для меня в Python 3. У меня есть список строк, и я просто хочу определить, какие из них содержат emoji. Какой самый быстрый способ сделать это?Как определить, содержит ли строка Python эмулятор?

Чтобы быть более конкретным, у меня есть длинный список строк темы письма из тестов AB, и я пытаюсь определить, какие строки темы содержат emoji.

+3

Смайлики или эмози? И в любом случае вам нужно сначала определить, что именно это означает для вас. –

+0

Я предлагаю попробовать [это] (http://stackoverflow.com/a/28327594/6464893). – Harrison

+0

Большинство предыдущих решений должно хорошо транслироваться на Python 3. Пожалуйста, разместите сообщение, которое вас поразит как «должно работать», и сообщение об ошибке, чтобы мы могли помочь с вашей конкретной проблемой. – Prune

ответ

1

this link и this link оба счета © и другие распространенные символы как эмози. Также у первого есть небольшие ошибки, и последний, похоже, не работает.

Вот реализация, которая ошибочно берется с консервативной стороны, используя this newer data и this documentation. Он учитывает только коды, отмеченные свойством unicode Emoji_Presentation (что означает, что это определенно emoji) или коды, отмеченные только свойством Emoji (что означает, что по умолчанию используется текст, но может быть emoji), то есть после чего следует специальная кодовая точка выбора выбора fe0f, которая вместо этого указывает на использование emoji. Причина, по которой я говорю это, консервативна, состоит в том, что некоторые системы не столь разборчивы относительно fe0f и будут обрабатывать персонажей как emoji, где бы они ни были (подробнее об этом here).

import re 
from collections import defaultdict 


def parse_line(line): 
    """Return a pair (property, codepoints) where property is a string and 
     codepoints is a set of int unicode code points""" 
    pat = r'([0-9A-Z]+)(\.\.[0-9A-Z]+)? + ; +(\w+) + #.*' 
    match = re.match(pat, line) 
    assert match 

    codepoints = set() 

    start = int(match.group(1), 16) 

    if match.group(2): 
     trimmed = match.group(2)[2:] 
     end = int(trimmed, 16) + 1 
    else: 
     end = start + 1 

    for cp in range(start, end): 
     codepoints.add(cp) 

    return (match.group(3), codepoints) 


def parse_emoji_data(): 
    """Return a dictionary mapping properties to code points""" 
    result = defaultdict(set) 
    with open('emoji-data.txt', mode='r', encoding='utf-8') as f: 
     for line in f: 
      if '#' != line[0] and len(line.strip()) > 0: 
       property, cp = parse_line(line) 
       result[property] |= cp 
    return result 


def test_parse_emoji_data(): 
    sets = parse_emoji_data() 
    sizes = { 
     'Emoji': 1123, 
     'Emoji_Presentation': 910, 
     'Emoji_Modifier': 5, 
     'Emoji_Modifier_Base': 83, 
    } 
    for k, v in sizes.items(): 
     assert len(sets[k]) == v 


def contains_emoji(text): 
    """ 
    Return true if the string contains either a code point with the 
    `Emoji_Presentation` property, or a code point with the `Emoji` 
    property that is followed by \uFE0F 
    """ 
    sets = parse_emoji_data() 
    for i, ch in enumerate(text): 
     if ord(ch) in sets['Emoji_Presentation']: 
      return True 
     elif ord(ch) in sets['Emoji']: 
      if len(text) > i+1 and text[i+1] == '\ufe0f': 
       return True 
    return False 

test_parse_emoji_data() 
assert not contains_emoji('hello') 
assert not contains_emoji('hello :) :D 125% #%&*(@#%&[email protected](^*(') 
assert contains_emoji('here is a smiley \U0001F601 !!!') 

Для его запуска необходимо ftp://ftp.unicode.org/Public/emoji/3.0/emoji-data.txt в рабочем каталоге.

Как только модуль регулярных выражений поддерживает свойства emoji, будет проще использовать это.

Смежные вопросы