# Ruby Twitter Search by punctuations

With twitter search the punctuation and special characters will be considered part of the term you're searching for, so searching for '#twitter!' will return '#twitter!', "twitter?', '#twitter', etc. What this module does is check if the search includes any type of punctuation searched with and if it does you can sort the array to add those tweets first. This code does the trick but I feel like there might be a cleaner way to do this. Right now I am just using array.sort and setting the array attributes index to 0 if it matches the regex which is looking for a punctuation used in the search and matching it with the tweets.

require 'twitter'

extend self

config.consumer_key        = ""
config.consumer_secret     = ""
config.access_token        = ""
config.access_token_secret = ""
end

# search returns
# Check out what @researchgoddess is up to at #sourcecon!
# What a welcome from @SourceCon! Thanks @CareerBuilder for hosting.#
# RT @JRoberts257: Happy hour at #SourceCon! Thanks @CareerBuilder for
# Happy hour at #SourceCon! Thanks @CareerBuilder for sponsoring. ht
# @RT @cybsearchjoe: #SourceCon is rocking
# etc

def search(text)
tweets = TWITTER_CLIENT.search("#{text} filter:images", result_type: "recent").take(30).collect do |tweet|
"#{tweet.text}"
end
# looks to see if there is puncuation at the end of the text "!.?{}[]" It will ignore the # at the beginning
tweets = sort_tweets(text, tweets) if text[1..text.length] =~ /[[:punct:]]/
puts tweets
end

# sorts tweets based off index given in match_phrase
def sort_tweets(text, tweets)
tweets.sort do |phrase, other_phrase|
match_phrase(phrase, text, tweets) <=> match_phrase(other_phrase, text, tweets)
end
end

# if phrase matches punc_text(text) the phrase will be inserted at the beginning of the array else it will return its previous index.
def match_phrase(phrase, text, tweets)
phrase.match(/#{punc_text(text)}/i).nil? ? tweets.index(phrase) + 1 : 0
end

# adds backslash to punctuation '#sourcecon//?|!|.'
def punc_text(text)
text[1..text.length].gsub(/([[:punct:]])/){|punc| "\\#{punc}"}
end
end



• Make the helper methods private using private_class_method ...
• I'm not quite sure why you are stripping out the leading # in several places. If you know that all searches are going to start with # then I would strip it out at the beginning (or expect the caller not to pass it in).
• if text[1..text.length] =~ /[[:punct:]]/ could be written as if text =~ /.[[:punct:]]/
• text[1..text.length].gsub(/([[:punct:]])/){|punc| "\\#{punc}"} There are two better ways to do this (1) Using backreferences text[1..text.length].gsub(/([[:punct:]])/, '\\\1') but (2) it really looks like you are trying to duplicate RegExp.escape
• phrase.match(/#{punc_text(text)}/i).nil?, I would think that phrase.downcase.include?(text.downcase) would be cleaner