Разбор твита для извлечения хэштегов в массив в Python
У меня есть время, затрачивающее информацию в твиттере, включая хэштеги, и вытягивание каждого хэштега в массив с использованием Python. Я смущен даже поставить то, что я пытался до сих пор.
Например, "Мне нравится #stackoverflow, потому что #people очень #helpful!"
Это должно вывести 3 хэштега в массив.
Ответы
Ответ 1
Простое регулярное выражение должно выполнить задание:
>>> import re
>>> s = "I love #stackoverflow because #people are very #helpful!"
>>> re.findall(r"#(\w+)", s)
['stackoverflow', 'people', 'helpful']
Обратите внимание, что, как было предложено в других ответах, это может также найти не-хэштеги, такие как хэш-местоположение в URL-адресе:
>>> re.findall(r"#(\w+)", "http://example.org/#comments")
['comments']
Итак, еще одним простым решением будет следующее (удаляет дубликаты в качестве бонуса):
>>> def extract_hash_tags(s):
... return set(part[1:] for part in s.split() if part.startswith('#'))
...
>>> extract_hash_tags("#test http://example.org/#comments #test")
set(['test'])
Ответ 2
>>> s="I love #stackoverflow because #people are very #helpful!"
>>> [i for i in s.split() if i.startswith("#") ]
['#stackoverflow', '#people', '#helpful!']
Ответ 3
Ответ AndiDogs будет испорчен ссылками и другими вещами, вы можете сначала отфильтровать их. После этого используйте этот код:
UTF_CHARS = ur'a-z0-9_\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff'
TAG_EXP = ur'(^|[^0-9A-Z&/]+)(#|\uff03)([0-9A-Z_]*[A-Z_]+[%s]*)' % UTF_CHARS
TAG_REGEX = re.compile(TAG_EXP, re.UNICODE | re.IGNORECASE)
Это может показаться излишним, но здесь оно было преобразовано http://github.com/mzsanford/twitter-text-java.
Он будет обрабатывать как 99% всех хэштегов так же, как твиттер обрабатывает их.
Для более преобразованного регулярного выражения твиттера проверьте это: http://github.com/BonsaiDen/Atarashii/blob/master/atarashii/usr/share/pyshared/atarashii/formatter.py
EDIT:
Отъезд: http://github.com/BonsaiDen/AtarashiiFormat
Ответ 4
Предположим, что вам нужно извлечь ваш #Hashtags
из предложения, полного символов пунктуации. Скажем, что #stackoverflow #people
и #helpful
заканчиваются разными символами, вы хотите получить их из text
, но вы можете избежать повторений:
>>> text = "I love #stackoverflow, because #people... are very #helpful! Are they really #helpful??? Yes #people in #stackoverflow are really really #helpful!!!"
если вы попытаетесь только с помощью set([i for i in text.split() if i.startswith("#")])
, вы получите:
>>> set(['#helpful???',
'#people',
'#stackoverflow,',
'#stackoverflow',
'#helpful!!!',
'#helpful!',
'#people...'])
который, на мой взгляд, лишний. Лучшее решение с использованием RE с модулем re
:
>>> import re
>>> set([re.sub(r"(\W+)$", "", j) for j in set([i for i in text.split() if i.startswith("#")])])
>>> set(['#people', '#helpful', '#stackoverflow'])
Теперь это нормально для меня.
EDIT: UNICODE #Hashtags
Добавьте флаг re.UNICODE
, если вы хотите удалить пунктуации, но сохраняя буквы с акцентами, апострофами и другими закодированными в кодировке Юникодом материалами, которые могут быть важны, если можно ожидать, что #Hashtags
не будет только на английском языке. возможно, это только кошмар итальянского парня, может быть, нет!; -)
Например:
>>> text = u"I love #stackoverflòw, because #peoplè... are very #helpfùl! Are they really #helpfùl??? Yes #peoplè in #stackoverflòw are really really #helpfùl!!!"
будет кодироваться в виде unicode как:
>>> u'I love #stackoverfl\xf2w, because #peopl\xe8... are very #helpf\xf9l! Are they really #helpf\xf9l??? Yes #peopl\xe8 in #stackoverfl\xf2w are really really #helpf\xf9l!!!'
и вы можете получить свой (правильно закодированный) #Hashtags
следующим образом:
>>> set([re.sub(r"(\W+)$", "", j, flags = re.UNICODE) for j in set([i for i in text.split() if i.startswith("#")])])
>>> set([u'#stackoverfl\xf2w', u'#peopl\xe8', u'#helpf\xf9l'])
EDITx2: UNICODE #Hashtags
и управление для #
повторений
Если вы хотите управлять несколькими повторениями символа #
, как в (простите меня, если пример text
стал почти нечитаемым):
>>> text = u"I love ###stackoverflòw, because ##################peoplè... are very ####helpfùl! Are they really ##helpfùl??? Yes ###peoplè in ######stackoverflòw are really really ######helpfùl!!!"
>>> u'I love ###stackoverfl\xf2w, because ##################peopl\xe8... are very ####helpf\xf9l! Are they really ##helpf\xf9l??? Yes ###peopl\xe8 in ######stackoverfl\xf2w are really really ######helpf\xf9l!!!'
то вы должны заменить эти множественные вхождения уникальным #
.
Возможным решением является введение другого вложенного неявного определения set()
с помощью функции sub()
, заменяющей вхождения более чем 1 #
одним синтаксисом #
:
>>> set([re.sub(r"#+", "#", k) for k in set([re.sub(r"(\W+)$", "", j, flags = re.UNICODE) for j in set([i for i in text.split() if i.startswith("#")])])])
>>> set([u'#stackoverfl\xf2w', u'#peopl\xe8', u'#helpf\xf9l'])
Ответ 5
простой смысл (лучше, чем выбранный ответ)
https://gist.github.com/mahmoud/237eb20108b5805aed5f
также работать с хэштегами unicode
Ответ 6
hashtags = [word for word in tweet.split() if word[0] == "#"]
Ответ 7
У меня было много проблем с юникодными языками.
Я видел много способов извлечь хэштег, но нашел, что они не ответили на все случаи
поэтому я написал небольшой код python для обработки большинства случаев. он работает для меня.
def get_hashtagslist(string):
ret = []
s=''
hashtag = False
for char in string:
if char=='#':
hashtag = True
if s:
ret.append(s)
s=''
continue
# take only the prefix of the hastag in case contain one of this chars (like on: '#happy,but i..' it will takes only 'happy' )
if hashtag and char in [' ','.',',','(',')',':','{','}'] and s:
ret.append(s)
s=''
hashtag=False
if hashtag:
s+=char
if s:
ret.append(s)
return list(set([word for word in ret if len(ret)>1 and len(ret)<20]))
Ответ 8
Лучшее регулярное выражение хэштега Twitter:
import re
text = "#promovolt #1st # promovolt #123"
re.findall(r'\B#\w*[a-zA-Z]+\w*', text)
>>> ['#promovolt', '#1st']
![enter image description here]()
Ответ 9
Я извлек хэштеги глупым, но эффективным способом.
def retrive(s):
indice_t = []
tags = []
tmp_str = ''
s = s.strip()
for i in range(len(s)):
if s[i] == "#":
indice_t.append(i)
for i in range(len(indice_t)):
index = indice_t[i]
if i == len(indice_t)-1:
boundary = len(s)
else:
boundary = indice_t[i+1]
index += 1
while index < boundary:
if s[index] in "'[email protected]#$%^&*()-_=+[]{}|\\:;'"",.<>?/ \n\t":
tags.append(tmp_str)
tmp_str = ''
break
else:
tmp_str += s[index]
index += 1
if tmp_str != '':
tags.append(tmp_str)
return tags