Create a regex that returns an array - ruby

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.

Related

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"

looping through scan and replacing matches individually

I would like to loop through regex matches and replace each match individually in the loop.
For example:
content.scan(/myregex/).each do |m|
m = 'new str'
end
How could I do that?
The reason why I want to do that is because each match will be replaced with a different output from a function.
Thanks for help
The following form of the gsub method will do exactly what you want:
gsub(pattern) {|match| block } → new_str
See http://ruby-doc.org/core-2.0.0/String.html#method-i-gsub for documentation.
If you're looking for the same thing every time then you could just do:
def some_function_here(args)
.... some logic creates replacement
while something == true
content.sub(/myregex/, replacement)
.... some logic to change replacement/or a call to a helper function
end
end
Not sure how you're generating the new replacement values, but from what I gather it appears that the easiest way to do it is to call the sub method on the string for your regex and replace them one at a time.

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

How to compare a string against multiple other strings

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")

Resources