using url in a string in ruby - ruby-on-rails

I want to convert urls in a string to workable urls. For example:
str = "Hello, this is the link for yahoo: http://www.yahoo.com"
//in the view i have
<%= parse_description(r[:description]) %>
//in helper, i am splitting each word in the string and verifying if i have a string which
// contains http, if http is present then i am using link_to to make it a valid url:
def parse_description(str)
s = ""
str.split.each do |w|
a = w.include?("http") ? (link_to nil,"#{w}") : w
s += "#{a} "
end
end
once the string is returned back to the view, the link is not clickable. what wrong i am doing?

Thanks pst for your help.. while returning i just did s.html_safe.. it worked.

To match the URI's in a String use the following code:
html_string.scan(URI.regexp) do |*matches|
p $&
end

Related

Camelize up to a certain part of a string

I have:
s = "like_so__case"
camelize gives this:
s.camelize # => "LikeSoCase"
I'm looking for conversion up to a double underscore __ to get:
"LikeSo__case"
How can I camelize only up to a certain part of a string?
The simplest option is to gsub part of your string.
'like_so__case'.gsub(/(.*?)(__.*)/) { "#{$1.camelize}#{$2}" }
#=> "LikeSo__case"
UPDATE
Cleaner and faster way arising from comments.
'like_so__case__h'.sub(/(.*?)(?=__)/, &:camelize)
#=> "LikeSo__case__h"
s = "like_so__case"
=> "like_so__case"
s.split('__', 2).tap { |s| s[0] = s[0].camelize }.join('__')
=> "LikeSo__case"
You of course could wrap it in string method
For getting this LikeSo__case, we can do like:
s="like_so__case"
s.split('__').tap { |s| s[0] = s[0].camelize }.join('__')
Your description on the demand is not so clear.
From your excepted result, I understand it as 'camelize a part of string until a pattern'. I should note one thing first that camelize is not part of Ruby's standard library of class String. ActiveSupport::Inflector provides it.
So if you want to just camelize each part divided by a pattern, use str.split('_').map(&:capitalize).join('_'). In your case, it returns 'Like_So__Case'.
Ruby's String has another instance method named partition, which splits the string into three parts (an array):
Part before the pattern
The pattern
Part after the pattern
So str.partition('__').tap { |a| a[0] = a[0].split('_').map(&:capitalize).join }.join should be your answer in plain Ruby.
No need of relying on camelize. Simply, this:
"like_so__case"
.gsub(/_?([a-z])([a-z]*)(?=.*__)/i){$1.upcase + $2.downcase}
# => "LikeSo__case"
def camelize(s)
for i in 0..s.size-2 do
if s[i] == "_" and s[i+1] == "_"
next
elsif s[i] == "_" and s[i+1] != "_" and s[i-1] != "_"
s[i+1] = s[i+1].upcase
s[i] = ""
else
next
end
end
return s
end
Use this method to solve your problem
s = "like_so__case"
i = s.index('__')
#=> 7
s.tap { |s| s[0,i] = s[0,i].camelize }
#=> LikeSo__case
The last line could be replaced by two lines:
s[0,i] = s[0,i].camelize
s
If the original string is not to be mutated write
s.dup.tap { |s| s[0,i] = s[0,i].camelize }

Lua gsub regex to replace multiple occurances of characters

I am trying to modify my URL to be clean and friendly by removing more than one occurrence of specific characters
local function fix_url(str)
return str:gsub("[+/=]", {["+"] = "+", ["/"] = "/", ["="] = "="}) --Needs some regex to remove multiple occurances of characters
end
url = "///index.php????page====about&&&lol===you"
output = fix_url(url)
What I would like to achieve the output as is this :
"/index.php?page=about&lol=you"
But instead my output is this :
"///index.php????page====about&&&lol===you"
Is gsub the way i should be doing this ?
I don't see how to do this with one call to gsub. The code below does this by calling gsub once for each character:
url = "///index.php????page====about&&&lol===you"
function fix_url(s,C)
for c in C:gmatch(".") do
s=s:gsub(c.."+",c)
end
return s
end
print(fix_url(url,"+/=&?"))
Here's one possible solution (replace %p with whatever character class you like):
local
function fold(s)
local ans = ''
for s in s:gmatch '.' do
if s ~= ans:sub(-1) then ans = ans .. s end
end
return ans
end
local
function fix_url(s)
return s:gsub('%p+',fold) --remove multiple same characters
end
url = '///index.php????page====about&&&lol===you'
output = fix_url(url)
print(output)

Simple string concatenation in rails in view page

I am new to Rails. Can someone please explain to me the concept of string concatenation using variables in view page and the controller?
For example :
In controller Code :
def show
#firstname = 'Test'
#lastname = 'User'
end
In view page :
Full Name : <%= "#{#firstname} #{lastname}" %>
For further details Click Here
Scenarios:- If you want to keep two variables on View page and add concatenation for those then use of space is necessary.
View page:
<%
var string_1 = "With"
var string_2 = "Rails"
var addition_1 = string_1 + string_2;
var addition_2 = string_1 + " " + string_2
%>
<h1> First Addition -> #{addition_1} </h1>
<h1> Second Addition -> #{addition_2} </h1>
Output :
First Addition -> WithRails
Second Addition -> With Rails
in view
<%
var1 = "ruby"
var2 = "on"
var3 = var1 + var2
%>
Finally
<% f_var = "Ruby #{var3}"%>
but this type of code is not recommended in view as it does not look good. You should use helper method for this type of requirement

Ruby On Rails: Concatenate String in loop

I am new to RoR. I was trying to find a way over googling to concatenate the string in a loop in Controller.
assets = Asset.where({ :current_status => ["active"] }).all
assets.each do |a|
string = string + ":"+ a.movie_title
end
I want to concatenate attribute "movie_title" as a string that would be colon separated.
but i get error
undefined method `+' for nil:NilClass
The easiest way is probably:
string = assets.collect(&:movie_title).join(':')
collect(&:movie_title) is the same as collect { |asset| asset.movie_title }, which returns an Array of the movie titles. join(':') creates a String with the values from the Array separated by :.
Try this
assets = Asset.where({ :current_status => ["active"] }).all
string = ""
if assets.present?
assets.each do |a|
string = string + ":"+ a.movie_title
end
end
Why not just this:
"#{string} : #{a.movie_title}"
If they are nil you will get " : "
Methods join (docs) and map (docs) may help you.
Try following:
assets = Asset.where(current_status: ["active"]).all
assets.map(&:movie_title).join(':')

How do I strip a URL from a string and place it an array?

I'm working on building a small script that searches for the 5 most recent pictures tweeted by a service, isolates the URL and puts that URL into an array.
def grabTweets(linkArray) #brings in empty array
tweets = Twitter.search("[pic] "+" url.com/r/", :rpp => 2, :result_type => "recent").map do |status|
tweets = "#{status.text}" #class = string
url_regexp = /http:\/\/\w/ #isolates link
url = tweets.split.grep(url_regexp).to_s #chops off link, turns link to string from an array
#add link to url array
#print linkArray #prints []
linkArray.push(url)
print linkArray
end
end
x = []
timelineTweets = grabTweets(x)
The function is returning things like this: ["[\"http://t.co/6789\"]"]["[\"http://t.co/12345\"]"]
I'm trying to get it to return ["http://t.co/6789", "http://t.co/1245"] but it's not managing that.
Any help here would be appreciated. I'm not sure what I'm doing wrong.
The easiest way to grab URLs in Ruby is to use the URI::extract method. It's a pre-existing wheel that works:
require 'uri'
require 'open-uri'
body = open('http://www.example.com').read
urls = URI::extract(body)
puts urls
Which returns:
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
http://www.w3.org/1999/xhtml
http://www.icann.org/
mailto:iana#iana.org?subject=General%20website%20feedback
Once you have the array you can filter for what you want, or you can give it a list of schemes to extract.
To strip a url out a string and push into urls array, you can do:
urls = []
if mystring =~ /(http:\/\/[^\s]+)/
urls << $1
end
grep returns an array:
grep(pattern) → array
grep(pattern) {| obj | block } → array
Returns an array of every element in enum for which Pattern === element.
So your odd output is coming from the to_s call the follows your grep. You're probably looking for this:
linkArray += tweets.split.grep(url_regexp)
or if you only want the first URL:
url = tweets.split.grep(url_regexp).first
linkArray << url if(url)
You could also skip the split.grep and use scan:
# \S+ should be good enough for this sort of thing.
linkArray += tweets.scan(%r{https?://\S+})
# or
url = tweets.scan(%r{https?://\S+}).first
linkArray << url if(url)

Resources