Как найти и подсчитать смайлики в строке с помощью python?

Эта тема была адресована для текстовых смайликов в link1 , link2 , link3 . Тем не менее, я хотел бы сделать что-то немного отличное от соответствия простым смайликам. Я сортирую твиты, содержащие значки смайликов. Следующая информация в Юникоде содержит только такие смайлики: pdf .

Используя строку с английскими словами, которая также содержит любые из этих смайликов из pdf , я хотел бы иметь возможность сравнить количество смайликов с количеством слов.

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

$cat <file containing the strings with emoticons> | ./emo.py 

emo.py скрипт psuedo:

 import re import sys for row in sys.stdin: print row.decode('utf-8').encode("ascii","replace") #insert regex to find the emoticons if match: #do some counting using .split(" ") #print the counting 

Проблема, с которой я сталкиваюсь, – это декодирование / кодирование. Я не нашел хороший вариант для того, как кодировать / декодировать строку, чтобы я мог правильно находить значки. Пример строки, которую я хочу найти, чтобы найти количество слов и смайликов, выглядит следующим образом:

«Смайлики эмоций! введите описание изображения здесь Ты мне нравишься введите описание изображения здесь «.

Задача: можете ли вы создать скрипт, который подсчитывает количество слов и смайликов в этой строке? Обратите внимание, что смайлики сидят рядом со словами без пробелов между ними.

2 Solutions collect form web for “Как найти и подсчитать смайлики в строке с помощью python?”

Во-первых, здесь нет необходимости кодировать. У вас есть строка Unicode, и механизм re может обрабатывать Unicode, поэтому просто используйте его.

Класс символов может включать в себя ряд символов, указав первый и последний с дефисом между ними. И вы можете указать символы Unicode, которые вы не знаете, как вводить с помощью \U escape-последовательностей. Так:

 import re s=u"Smiley emoticon rocks!\U0001f600 I like you.\U0001f601" count = len(re.findall(ru'[\U0001f600-\U0001f650]', s)) 

Или, если строка достаточно большая, чтобы создать весь список findall кажется расточительным:

 emoticons = re.finditer(ru'[\U0001f600-\U0001f650]', s) count = sum(1 for _ in emoticons) 

Подсчитав слова, вы можете сделать это отдельно:

 wordcount = len(s.split()) 

Если вы хотите сделать все сразу, вы можете использовать группу чередования:

 word_and_emoticon_count = len(re.findall(ru'\w+|[\U0001f600-\U0001f650]', s)) 

Как указывает @strangefeatures, версии Python до 3.3 допускают сборку «узких Unicode». И, например, большинство сборок CPython Windows узки. В узких строках символы могут находиться только в диапазоне U+0000 до U+FFFF . Невозможно найти эти символы, но это нормально, потому что их не существует для поиска; вы можете просто предположить, что они не существуют, если вы получаете ошибку «недопустимый диапазон», компилируя регулярное выражение.

Кроме того, конечно, есть хорошая вероятность, что везде, где вы получаете свои фактические строки, это UTF-16-BE или UTF-16-LE, поэтому символы существуют, они просто закодированы в суррогатные пары , И вы хотите совместить эти суррогатные пары, верно? Поэтому вам нужно перевести поиск в поиск суррогатной пары. То есть, конвертируйте свои высокие и низкие коды в суррогатные парные коды, затем (в терминах Python) выполните поиск:

 (lead == low_lead and lead != high_lead and low_trail <= trail <= DFFF or lead == high_lead and lead != low_lead and DC00 <= trail <= high_trail or low_lead < lead < high_lead and DC00 <= trail <= DFFF) 

Вы можете оставить второе условие в последнем случае, если вас не беспокоит принятие поддельного UTF-16.

Если не очевидно, как это переводится в regexp, вот пример диапазона [\U0001e050-\U0001fbbf] в UTF-16-BE:

 (\ud838[\udc50-\udfff])|([\ud839-\ud83d].)|(\ud83e[\udc00-\udfbf]) 

Конечно, если ваш диапазон достаточно мал, что low_lead == high_lead становится проще. Например, диапазон исходного вопроса можно найти с помощью:

 \ud83d[\ude00-\ude50] 

Один последний трюк, если вы действительно не знаете, собираетесь ли вы получать UTF-16-LE или UTF-16-BE (и спецификация находится далеко от данных, которые вы ищете): поскольку суррогатное лидерство или блок кода трейла действителен как отдельный символ или как другой конец пары, вы можете просто выполнить поиск в обоих направлениях:

 (\ud838[\udc50-\udfff])|([\ud839-\ud83d][\udc00-\udfff])|(\ud83e[\udc00-\udfbf])| ([\udc50-\udfff]\ud838)|([\udc00-\udfff][\ud839-\ud83d])|([\udc00-\udfbf]\ud83e) 

Если вы пытаетесь читать символы юникода за пределами диапазона ascii, не конвертируйте в диапазон ascii. Просто оставьте его как unicode и работайте оттуда (непроверенный):

 import sys count = 0 emoticons = set(range(int('1f600',16), int('1f650', 16))) for row in sys.stdin: for char in row: if ord(char) in emoticons: count += 1 print "%d emoticons found" % count 

Не лучшее решение, но оно должно работать.

  • Python: передача строки Unicode в модуль C ++
  • Django создает CSV-файл, который содержит Unicode и может быть открыт непосредственно с помощью Excel
  • Кодировка Python для pipe.communicate
  • Что означает sys.maxunicode?
  • Django: символ не-ASCII
  • Как декодировать необработанные литералы Unicode для читаемой строки?
  • Каков правильный способ использования символов Юникода в регулярном выражении python
  • Является ли u'string 'таким же, как' string'.decode ('XXX')
  • Python - лучший язык программирования в мире.