I want to convert the string:
"{john:123456}"
to:
"<script src='https://gist.github.com/john/123456.js'>"
I wrote a method that works, but it is very stupid. It is like this:
def convert
args = []
self.scan(/{([a-zA-Z0-9\-_]+):(\d+)}/) {|x| args << x}
args.each do |pair|
name = pair[0]
id = pair[1]
self.gsub!("{" + name + ":" + id + "}", "<script src='https://gist.github.com/#{name}/#{id}.js'></script>")
end
self
end
Is there a way to do this just like the cool_method below?
"{john:123}".cool_method(/{([a-zA-Z0-9\-_]+):(\d+)}/, "<script src='https://gist.github.com/$1/$2.js'></script>")
That cool method is gsub. You were so close! Just change the $1 and $2 to \\1 and \\2
http://ruby-doc.org/core-2.0/String.html#method-i-gsub
"{john:123}".gsub(/{([a-zA-Z0-9\-_]+):(\d+)}/,
"<script src='https://gist.github.com/\\1/\\2.js'></script>")
I would do
def convert
/{(?<name>[a-zA-Z0-9\-_]+):(?<id>\d+)}/ =~ self
"<script src='https://gist.github.com/#{name}/#{id}.js'></script>"
end
Please see http://ruby-doc.org/core-2.0/Regexp.html#label-Capturing for more details.
s = "{john:123456}".scan(/\w+|\d+/).each_with_object("<script src='https://gist.github.com") do |i,ob|
ob<< "/" + i
end.concat(".js'>")
p s #=> "<script src='https://gist.github.com/john/123456.js'>"
That looks like a JSON string, so, as #DaveNewton said, treat it as one:
require 'json'
json = '{"john":123456}'
name, value = JSON[json].flatten
"<script src='https://gist.github.com/#{ name }/#{ value }.js'></script>"
=> "<script src='https://gist.github.com/john/123456.js'></script>"
Why not treat it as a string and use a regular expression on it? Because JSON isn't a simple format for parsing via regular expressions, which can cause errors as the values change or the data string gets more complex.
Related
I am a beginner in Ruby. Could someone help me with this?
I want to call a method within ""
def callme
"this string" # this is usually a path that I want to source from a single location
end
v= "string + callme "
how do I call the function within quotes here? The quotes are essential for my code.
You can use string interpolation / concatenation:
def hi
'Hello'
end
def world
'World'
end
# Concatenation
hi + ' ' + world #=> "Hello World"
# Interpolation
"#{hi} #{world}" #=> "Hello World"
See this answer for more details
If I understand correctly, what you are looking for is string interpolation. The syntax for this is #{...}, like so:
v= "string + #{callme} "
This sets the variable v to "string + this string ".
Reference
What I'm trying to do:
I'm trying to display and log a regex value I use for to search a String.
The problem:
Even to_s doesn't work. I ended up using dummy regexD to display it.
What I don't know how to do:
Is there a good way to convert alpha regex into char?
Context:
$VERBOSE = nil
regex = /alpha.centavra/i #
regexD= 'alpha.centavra' # to display
puts "1. Search for: " + regex.to_s ## (?i-mx:alpha.centavra)
puts "2. Search for: " + regex.to_s.gsub!('(?i-mx:','').gsub!(')','')
File.open('D:/x/test.dat', 'w') { |f| f.write ('Search for ' + regex.to_s) }
You need to call .source on your regex.
regex = /alpha.centavra/i
regex.source # => "alpha.centavra"
I am trying to use this line of code here:
longest = twoOfArray.inject(0) {|memo,word| memo > word.length ? memo : word.length},
and put it into this printf on this line like this:
twoOfArray.each {|k, v| puts "%-*.*s" % [longest] + " " + '*'*v }
However, it gives me the error:
%': too few arguments (ArgumentError)
Does this mean that something is wrong with my longest variable? Or is my syntax wrong? I cant seem to fix the problem. Does anyone see whats wrong here?
The format string "%-*.*s" expects three arguments: two numbers (one for each*`) and a string. Your array only contains a single argument.
hash = {"it"=>3, "was"=>3, "the"=>3, "of"=>2, "times"=>2}
words_array = hash.keys
longest_word = words_array.max_by {|word| word.length}
max_len = longest_word.size
words_array.each do |word|
number = hash[word]
str = "#{'*' * (max_len - number)}#{word}#{'*' * number}"
puts str
end
--output:--
**it***
**was***
**the***
***of**
***times**
mystring = "svn-myapplication" or mystring = "git-myapplication"
My desired output:
mystring = "myapplications(svn)"
mystring = "myapplication(git)"
Question: The first 3 characters of the string should be moved to the last with enclosed brackets and the "-" should be removed.
I tried to do something like this:
mystring.gsub('svn-','')+"(svn)" but svn might be git, so i want to use the first three characters to be moved to end with "-" removed and brackets enclosed
A regular expression with groups would work well:
mystring.gsub(/^([a-z]+)-(\w+)/, '\2(\1)')
Lets rock'n'roll :)
mystring = "svn-myapplication"
mystring.split('-').rotate.join('(') + ')'
You could use e regular expression but the simplest solution is as follows
mystring = "svn-myapplication"
puts "#{mystring[4..-1]}(#{mystring[0..2]})"
gives
myapplication(svn)
You can use the [] method of Ruby's String class for this:
mystring = "svn-myapplication"
mystring = "#{mystring[4..-1]}(#{mystring[0,3]})"
You can try something like this in irb
1.9.3-p362 :001 > mystring = "svn-myapplication"
1.9.3-p362 :002 > mystring.gsub(mystring[0,3]+'-','')+(mystring[0,3])
I was going to submit this but, at least I can see how to do it better!
def test(s = '')
match = /\w+-/.match(s).to_s
match = match[0..-2]
s.gsub!(/\w+-/, '')
s << "(#{match})"
end # of test
This is what I have now - which looks too verbose for the work it is doing.
#title = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil?
Assume tokens is a array obtained by splitting a CSV line.
now the functions like strip! chomp! et. all return nil if the string was not modified
"abc".strip! # => nil
" abc ".strip! # => "abc"
What is the Ruby way to say trim it if it contains extra leading or trailing spaces without creating copies?
Gets uglier if I want to do tokens[Title].chomp!.strip!
I guess what you want is:
#title = tokens[Title]
#title.strip!
The #strip! method will return nil if it didn't strip anything, and the variable itself if it was stripped.
According to Ruby standards, a method suffixed with an exclamation mark changes the variable in place.
Update: This is output from irb to demonstrate:
>> #title = "abc"
=> "abc"
>> #title.strip!
=> nil
>> #title
=> "abc"
>> #title = " abc "
=> " abc "
>> #title.strip!
=> "abc"
>> #title
=> "abc"
Btw, now ruby already supports just strip without "!".
Compare:
p "abc".strip! == " abc ".strip! # false, because "abc".strip! will return nil
p "abc".strip == " abc ".strip # true
Also it's impossible to strip without duplicates. See sources in string.c:
static VALUE
rb_str_strip(VALUE str)
{
str = rb_str_dup(str);
rb_str_strip_bang(str);
return str;
}
ruby 1.9.3p0 (2011-10-30) [i386-mingw32]
Update 1:
As I see now -- it was created in 1999 year (see rev #372 in SVN):
Update2:
strip! will not create duplicates — both in 1.9.x, 2.x and trunk versions.
There's no need to both strip and chomp as strip will also remove trailing carriage returns - unless you've changed the default record separator and that's what you're chomping.
Olly's answer already has the canonical way of doing this in Ruby, though if you find yourself doing this a lot you could always define a method for it:
def strip_or_self!(str)
str.strip! || str
end
Giving:
#title = strip_or_self!(tokens[Title]) if tokens[Title]
Also keep in mind that the if statement will prevent #title from being assigned if the token is nil, which will result in it keeping its previous value. If you want or don't mind #title always being assigned you can move the check into the method and further reduce duplication:
def strip_or_self!(str)
str.strip! || str if str
end
As an alternative, if you're feeling adventurous you can define a method on String itself:
class String
def strip_or_self!
strip! || self
end
end
Giving one of:
#title = tokens[Title].strip_or_self! if tokens[Title]
#title = tokens[Title] && tokens[Title].strip_or_self!
If you are using Ruby on Rails there is a squish
> #title = " abc "
=> " abc "
> #title.squish
=> "abc"
> #title
=> " abc "
> #title.squish!
=> "abc"
> #title
=> "abc"
If you are using just Ruby you want to use strip
Herein lies the gotcha.. in your case you want to use strip without the bang !
while strip! certainly does return nil if there was no action it still updates the variable so strip! cannot be used inline. If you want to use strip inline you can use the version without the bang !
strip! using multi line approach
> tokens["Title"] = " abc "
=> " abc "
> tokens["Title"].strip!
=> "abc"
> #title = tokens["Title"]
=> "abc"
strip single line approach... YOUR ANSWER
> tokens["Title"] = " abc "
=> " abc "
> #title = tokens["Title"].strip if tokens["Title"].present?
=> "abc"
If you want to use another method after you need something like this:
( str.strip || str ).split(',')
This way you can strip and still do something after :)
I think your example is a sensible approach, although you could simplify it slightly as:
#title = tokens[Title].strip! || tokens[Title] if tokens[Title]
Alternative you could put it on two lines:
#title = tokens[Title] || ''
#title.strip!
If you have either ruby 1.9 or activesupport, you can do simply
#title = tokens[Title].try :tap, &:strip!
This is really cool, as it leverages the :try and the :tap method, which are the most powerful functional constructs in ruby, in my opinion.
An even cuter form, passing functions as symbols altogether:
#title = tokens[Title].send :try, :tap, &:strip!
My way:
> (#title = " abc ").strip!
=> "abc"
> #title
=> "abc"
#title = tokens[Title].strip! || tokens[Title]
It's entirely possible i'm not understanding the topic, but wouldn't this do what you need?
" success ".strip! || "rescue" #=> "success"
"failure".strip! || "rescue" #=> "rescue"