I have a list of names in an array in Ruby:
names = ["John Smith","Bob Miller"]
So I want to do a regex and get this array:
namesRegex = ["JS","BM"]
This is, I extract the uppercase characters from the string, merge them and put them in a new array.
Any help is appreciated.
This is really simple:
names.map { |name| name.gsub(/[^A-Z]/, '') }
You could very readily construct a less elegant but wholly valid solution to this problem that doesn't even require the use of regular expressions or mapping.
names.map { |name| name.scan(/\b\w/).*'' }
Related
I have a languages string, defined as: en,fr,nl_nl. I need to return the first element that starts with nl. How can I do this?
I've started with languages.split(','), but don't know what's the best way to search for a pattern in an array and return the first element.
This should work as you expect:
languages.split(',').detect { |s| s.start_with?('nl') }
# => "nl_nl"
Unless you need the array, you could use a regular expression to find the substring:
languages = 'en,fr,nl_nl'
languages[/\bnl[^,]*/] #=> "nl_nl"
languages[/\ben[^,]*/] #=> "en"
Here is my array:
a = ['a','b','c', 'C!', 'D!']
I would like to select any upcase letters followed by the ! character and display them. I was trying:
puts a.select! {|i| i.upcase + "!"}
which gave me null set. Any help would be greatly appreciated.
puts a.grep(/[A-Z]!/)
will do.
Try the following:
a.select {|i| i =~ /[A-Z]!/}
Here's another way using the Regexp match method in Ruby.
a.select { |letter| /[A-Z]!/.match(letter) }
Also, one note: consider a more meaningful and contextually relevant variable name than "i" in a.select! {|i| i.upcase + "!"}. For example, I chose the name "letter", although there may be a more meaningful name. It's just a good naming practice that a lot of Ruby programmers tend to follow. Same thing applies to the array named a.
In my app, I have to monitor what users type. So I have to prevent any bad words from the web site. Just for example, suppose all my bad words were in this array.
bad_words = ['bad', 'evil', 'terrible', 'villain', 'enemy']
If a user typed those, I would like them to be deleted. Here was one thing I tried.
bad_words.each {|word| string.gsub(word, '')}
Help is appreciated.
You can use a Gem to do the clean job:
https://github.com/tjackiw/obscenity
including the gem will allow you methods like:
Obscenity.configure { |config| config.whitelist = bad_words }
and then:
Obscenity.sanitize(string)
Here's one way:
bad_words = ['bad', 'evil', 'terrible', 'villain', 'enemy']
orig_str =
"Evil is embodied by a terrible villain named 'Bad' who plays badmitten"
no_bad_str = orig_str.gsub(/(?<=^|\W)\w+(?=\W|$)/) { |w|
(bad_words.include?(w.downcase)) ? '' : w }
#=> " is embodied by a named '' who plays badmitten"
(?<=^|\W) is a positive lookbehind
(?=\W|$) is a positive lookahead
Can bad, evil and terrible words sneak by? Of course. Some examples for orig_str:
badbadbad
evilterribleenemy
eviloff
flyingevil
Good luck!
You can either do
bad_words.each {|word| string = string.gsub(word, '')}
or
bad_words.each {|word| string.gsub!(word, '')}
Either should work issue with your original was that it was returning a new string not modifying the old one like the to solutions I have proposed above.
You can use Regexp.union to create a regular expression containing all the words in yours list:
bad_words = ['bad', 'evil', 'terrible', 'villain', 'enemy']
Regexp.union(bad_words)
# => /bad|evil|terrible|villain|enemy/
string.gsub(Regexp.union(bad_words), '')
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"
If I wanted to remove things like:
.!,'"^-# from an array of strings, how would I go about this while retaining all alphabetical and numeric characters.
Allowed alphabetical characters should also include letters with diacritical marks including à or ç.
You should use a regex with the correct character property. In this case, you can invert the Alnum class (Alphabetic and numeric character):
"◊¡ Marc-André !◊".gsub(/\p{^Alnum}/, '') # => "MarcAndré"
For more complex cases, say you wanted also punctuation, you can also build a set of acceptable characters like:
"◊¡ Marc-André !◊".gsub(/[^\p{Alnum}\p{Punct}]/, '') # => "¡MarcAndré!"
For all character properties, you can refer to the doc.
string.gsub(/[^[:alnum:]]/, "")
The following will work for an array:
z = ['asfdå', 'b12398!', 'c98347']
z.each { |s| s.gsub! /[^[:alnum:]]/, '' }
puts z.inspect
I borrowed Jeremy's suggested regex.
You might consider a regular expression.
http://www.regular-expressions.info/ruby.html
I'm assuming that you're using ruby since you tagged that in your post. You could go through the array, put it through a test using a regexp, and if it passes remove/keep it based on the regexp you use.
A regexp you might use might go something like this:
[^.!,^-#]
That will tell you if its not one of the characters inside the brackets. However, I suggest that you look up regular expressions, you might find a better solution once you know their syntax and usage.
If you truly have an array (as you state) and it is an array of strings (I'm guessing), e.g.
foo = [ "hello", "42 cats!", "yöwza" ]
then I can imagine that you either want to update each string in the array with a new value, or that you want a modified array that only contains certain strings.
If the former (you want to 'clean' every string the array) you could do one of the following:
foo.each{ |s| s.gsub! /\p{^Alnum}/, '' } # Change every string in place…
bar = foo.map{ |s| s.gsub /\p{^Alnum}/, '' } # …or make an array of new strings
#=> [ "hello", "42cats", "yöwza" ]
If the latter (you want to select a subset of the strings where each matches your criteria of holding only alphanumerics) you could use one of these:
# Select only those strings that contain ONLY alphanumerics
bar = foo.select{ |s| s =~ /\A\p{Alnum}+\z/ }
#=> [ "hello", "yöwza" ]
# Shorthand method for the same thing
bar = foo.grep /\A\p{Alnum}+\z/
#=> [ "hello", "yöwza" ]
In Ruby, regular expressions of the form /\A………\z/ require the entire string to match, as \A anchors the regular expression to the start of the string and \z anchors to the end.