How to compare a string against multiple other strings - ruby

Is there a method that let me compare one String with multiple others in Ruby? I really would like to do something like this:
myString.eql?(["string1","string2","string3"])

["string1","string2","string3"].include? myString

You could use Array#include? to see if the array includes the string:
%w(string1 string2 string3).include?(myString)

I find myself wanting this a lot, so I added a String method to be able to do it more idiomatically:
class String
def among?(*array)
array.flatten.include?(self)
end
end
Then
myString.among?("string1","string2","string3")

Related

Create a regex that returns an array

I am working in Ruby. I need to create a regex that takes in a string, I suppose, and returns an array with only the words that start with "un" and end with "ing". I have no clue how to do it :/
def words_starting_with_un_and_ending_with_ing(text)
!!text.capitalize.scan(/\A+UN\Z+ING/)
end
Something like this:
def uning string
string.scan(/\b[Uu]n[a-z]*ing\b/)
end
See String#scan for more info. For a nice interactive introduction to Regex take a look at RegexOne.

opposite of sub in ruby

I want to replace the content (or delete it) that does not match with my filter.
I think the perfect description would be an opposite sub. I cannot find anything similar in the docs, and I'm not sure how to invert the regex, but I think a method would probably be the more convenient.
An example of how it would work (I've just changed the words to make it more clear)
"bird.cats.dogs".opposite_sub(/(dogs|cats)\.(dogs|cats)/, '')
#"cats.dogs"
I hope it's easy enough to understand.
Thanks in advance.
String#[] can take a regular expression as its parameter:
▶ "bird.cats.dogs"[/(dogs|cats)\.(dogs|cats)/]
#⇒ "cats.dogs"
For multiple matches one can use String#scan:
▶ "bird.cats.dogs.bird.cats.dogs".scan /(?:dogs|cats)\.(?:dogs|cats)/
#⇒ ["cats.dogs", "cats.dogs"]
So you want to extract the part that matches your regex?
You can use String#slice, for example:
"bird.cats.dogs".slice(/(dogs|cats)\.(dogs|cats)/)
#=> "cats.dogs"
And String#[] does the same.
"bird.cats.dogs"[/(dogs|cats)\.(dogs|cats)/]
#=> "cats.dogs"
You cannot have a single replacement string because the part of the string that matches the regex might not be at the beginning or end of the string, in which case it's not clear whether the replacement string should precede or follow the matching string. I've therefore written the following with two replacement strings, one for pre-match, the other for post_match. I've made this a method of the String class as that's what you've asked for (though I've given the method a less-perfect name :-) )
class String
def replace_non_matching(regex, replace_before, replace_after)
first, match, last = partition(regex)
replace_before + match + replace_after
end
end
r = /(dogs|cats)\.(dogs|cats)/
"birds.cats.dogs.pigs".replace_non_matching(r, "", "")
#=> "cats.dogs"
"birds.cats.dogs".replace_non_matching(r, "snakes.", ".hens")
#=> "snakes.cats.dogs.hens"
"birds.cats.dogs.mice.cats.dogs.bats".replace_non_matching(r, "snakes.", ".hens")
#=> "snakes.cats.dogs.hens"
Regarding the last example, the method could be modified to replace "birds.", ".mice." and ".bats", but in that case three replacement strings would be needed. In general, determining in advance the number of replacement strings needed could be problematic.

Replace characters from string Ruby

I have the following string which has an array element in it and I will like to remove the quotes in the array element to the outside of the array:
"date":"2014-05-04","name":"John","products":["12","14","45"],"status":"completed"
Is there a way to remove the double quotes in [] and add double quotes to the start and end of []? Results:
"date":"2014-05-04","name":"John","products":"[12,14,45]","status":"completed"
Can that be done in ruby or is there a command line that I can use?
Your string looks like a json hash to me:
json = '{"date":"2014-05-04","name":"John","products":["12","14","45"],"status":"completed"}'
require 'json'
hash = JSON.load(json)
hash.update('products' => hash['products'].map(&:to_i))
puts hash.to_json
# => {"date":"2014-05-04","name":"John","products":[12,14,45],"status":"completed"}
Or if you really want to have the array represented as a string (what is not json anymore):
hash.update('products' => hash['products'].map(&:to_i).to_s) # note .to_s here
puts hash.to_json
# => {"date":"2014-05-04","name":"John","products":"[12,14,45]","status":"completed"}
The answer by #spickermann is pretty good, and the best way I can think of, but since I had fun trying to find an alternative without using json, here it goes:
def string_to_result(str)
str.match(/(?:\[)((?:")+(.)+(?:")+)+(?:\])/)
str.gsub($1, "#{$1.split(',').map{ |num| num.gsub('"', '') }.join(',')}").gsub(/\[/, '"[').gsub(/\]/, ']"').gsub(/String/, 'Results')
end
Is ugly as hell, but it works :P
I tried to do it on a single step, but that was way harder for my regexp skills.
Anyway, you should never parse something structured such as json or xml using only regexps, and this is merely for fun.
[EDIT] Had the bracket adjacent quotes wrong,sorry. Fixed.
Also, one more thing, this fails A LOT! An empty array or an array in other place in the string are just a few cases where it would fail.
You could use the form of String#gsub that takes a block:
str = '"2014-05-04","name":"John","products":["12","14","45"],"status":"completed"'
puts str.gsub(/\["(\d+)","(\d+)","(\d+)"\]/) { "\"[#{$1},#{$2},#{$3}]\"" }
#"2014-05-04","name":"John","products":"[12,14,45]","status":"completed"

Ruby PrettyPrint in single quote

how to make Ruby pp function outputing String in valid (parsable) Ruby string using single quote if possible?
rows = [{name:'test',id:'182572'},{name:"Kal'el",id:'125125'}]
require 'pp'
pp rows
output was:
[{:name=>"test", :id=>"182572"}, {:name=>"Kal'el", :id=>"125125"}]
desired output was:
[{:name=>'test', :id=>'182572'}, {:name=>"Kal'el", :id=>'125125'}]
(is it possible to use quote single quote inside single quote string?)
nevermind, i found the answer since my edit on sawa's answer has been rejected, i'll put it here:
class String
alias :old_inspect :inspect
def inspect
return old_inspect if self.include? "'"
"'#{self}'"
end
end
You can't. Strings, after parsing, aren't double or single quoted, they're just strings. If you want strings to appear with single quotes, you'll have to write your own printing function.
Redefine String#inspect.
class String
def inspect; "'#{self}'" end
end

Capitalizing a sentence

Is there a method (perhaps in some library from Rails) or an easy way that capitalizes the first letter of a string without affecting the upper/lower case status of the rest of the string? I want to use it to capitalize error messages. I expect something like this:
"hello iPad" #=> "Hello iPad"
There is a capitalize method in Ruby, but it will downcase the rest of the string. You can write your own otherwise:
class String
def capitalize_first
(slice(0) || '').upcase + (slice(1..-1) || '')
end
def capitalize_first!
replace(capitalize_first)
end
end
Edit: Added capitalize_first! variant.
Rather clumsy, but it works:
str = "hello IiPad"
str[0] = str[0].upcase #or .capitalize
Thanks to other answers, I realized some points that I need to be aware of, and also that there is no built in way. I looked into the source of camelize in Active Support of Rails as hinted by Vitaly Zemlyansky, which gave me a hint: that is to use a regex. I decided to use this:
sub(/./){$&.upcase}
Try this
"hello iPad".camelize

Resources