Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I am using Ruby on Rails to make a university-exclusive website that categorizes all registered users into their specific universities via their ".edu" email. Nearly all US-based universities have an "xyz.edu" email domain. In essence, everyone that signs up with their ".edu" email would all be categorized with a similar "domain.edu".
I've searched for a regex to look for like-domains.edu and assign them into a variable or specific indexes, but I must be looking in the wrong place because I cannot find how to do this.
Would I use regex for this? Or maybe a method after their email has been verified?
I would appreciate any help or feedback I can get.
You could use a regex to extract domain names:
"gates#harvard.edu" =~ /.*#(.*)$/
This simple regexp will capture everything after the # symbol. You can experiment more with this regexp here.
However, what you have to think about is how to handle cases like gates#harvard.edu vs gates#seas.harvard.edu.
My example will parse them out as different entities: harvard.edu vs seas.harvard.edu.
I would probably go ahead and create an institution/university/group model that would hold those users. It would be easier now than later down the line. But, in an effort to answer your question, you could do something like:
array_of_emails = ['d#xyz.edu', 'a#abc.edu', 'c#xyz.edu', 'b#abc.edu' ]
array_of_emails.sort_by! { |email| "#{email[email.index('#')..-1]}#{email[0..email.index('#')]}" }
EDIT: Changed sort! to sort_by!
Dealing with domains is going to get a lot more complex in the future, with new TLDs coming on line. Assuming that .edu is the only educational TLD will be wrong.
A simple way to grab just the domain for now is:
"gates#harvard.edu"[/(#.+)$/, 1] # => "#harvard.edu"
That will handle things like:
"gates#mail.harvard.edu"[/(#.+)$/, 1] # => "#mail.harvard.edu"
If you don't want the #, simply shift the opening parenthesis right one character:
pattern = /#(.+)$/
"gates#harvard.edu"[pattern, 1] # => "harvard.edu"
"gates#mail.harvard.edu"[pattern, 1] # => "mail.harvard.edu"
If you want to normalize the domain to strip off sub-domains, you can do something like:
pattern = /(\w+\.\w+)$/
"harvard.edu"[pattern, 1] # => "harvard.edu"
"mail.harvard.edu"[pattern, 1] # => "harvard.edu"
which only grabs the last two "words" that are separated by a single ..
That's somewhat naive, as non-US domains can have a country code, so if you need to handle those you can do something like:
pattern = /(\w+\.edu(?:\.\w+)?)$/
"harvard.edu"[pattern, 1] # => "harvard.edu"
"harvard.edu.cc"[pattern, 1] # => "harvard.edu.cc"
"mail.harvard.edu.cc"[pattern, 1] # => "harvard.edu.cc"
And, as to whether you should do this before or after you've verified their address? Do it AFTER. Why waste your CPU time and disk space processing invalid addresses?
array_of_emails = ['d#xyz.edu', 'a#abc.edu', 'c#xyz.edu', 'b#abc.edu' ]
x = array_of_emails.sort_by do | a | a.match(/#.*/)[0] end
x.each do |a|
puts a
end
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 months ago.
Improve this question
I started learning Ruby from scratch, from the preliminary preparation there is a certain knowledge of HTML and CSS. For training I use Code Academy. I have questions and can't always find an answer I can understand I need help understanding the following:
user_input = gets.chomp
user_input.downcase!
Explain why user_input is equivalent to gets.chomp and what that means, thanks in advance!
In Ruby = is used to assign values to variables, as in:
x = 1
y = x
Where y assumes the value of x at the moment that line is executed. This is not to be confused with "equivalence" as in x=y in a mathematical sense where you're establishing some kind of permanent relationship.
In Ruby methods return a value, even if that value is "nothing", or nil. In the case of gets, it returns a String. You can call chomp on that, or any other thing you need to achieve your objective, like chaining on downcase.
On its own gets.chomp will read a line of input, strip off the trailing linefeed character, and then throw the result in the trash. Assigning this to a variable preserves that output.
To understand it, break it down first
Accept user input
Clean the user input (using chomp https://apidock.com/ruby/String/chomp)
Downcase it
user_input = gets # will return the value entered by the user
user_input = user_input.chomp # will remove the trailing \n
# A more idiomatic way to achieve the above steps in a single line
user_input = gets.chomp
# Finally downcase
user_input.downcase!
# By that same principle the entire code can be written in a single line
user_input = gets.chomp.downcase
user_input is equivalent to gets.chomp
Remember, everything in Ruby is an object. So gets returns a String object, so does chomp and so does downcase. Hence with this logic you are essentially calling instance methods on the String class
String.new("hello") == "hello" # true
# "hello".chomp is same as String.new("hello").chomp
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
What can be the reason of string capitalization not working?
A database column:
t.string "name", limit: 255
Some example:
flower_name = Flower.find_by(id: 1).name #=> "chamomile©"
Trying to capitalize (got the same output):
flower_name.capitalize #=> "chamomile©"
Checking if it is string:
flower_name.is_a?(String) #=> true
capitalize works with ASCII characters only. Is there any chance your string contains non-ascii letters?
Try
flower_name.mb_chars.capitalize.to_s
mb_chars method may help you if you are using Rails >= 3.
'æ-ý'.mb_chars.upcase
=> "Æ-Ý"
If you're not using Rails, you can:
use directly active_support gem:
require 'active_support/core_ext/string/multibyte'
try unicode gem.
I hope you will find an answer in this similar question: Special character uppercase
This question already has answers here:
What does map(&:name) mean in Ruby?
(17 answers)
Closed 8 years ago.
I saw it in some sample Ruby code someone had posted. It was something like:
a.sort_by(&:name)
where a is an array or ActiveRecord objects and :name is one of the attributes.
I have never seen &:name and Ruby's Symbol class documentation says nothing about it. Probably something really simple. :)
Unary Ampersand is address of a function/block/lambda
In this case, it means that the .sort_by function will use each a's element's function named name for comparison
Mostly it used for something else, like this:
[1,2,3].map{ |x| x.to_s } # ['1','2','3']
That could be shortened as:
[1,2,3].map(&:to_s)
So, in your case, a.sort_by(&:name) is a shorthand to:
a.sort_by{ |x| x.name }
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Is there a way to create a regex for initials without using back references? For example, say I want initials for
New.York
And the regex to output
N.Y. (or n.y)
So far I have the following:
.\.[a-zA-Z]+
This outputs the last the initial of the first word instead of the first initial: w.y.
UPDATE**
I'm also assigned the RegExp to variable and using the =~ to test some things.
You could remove all the lowercase letters using gsub function,
irb(main):004:0> str = "New.York"
=> "New.York"
irb(main):006:0> str.gsub(/[a-z]+/, "")
=> "N.Y"
A ruby way to do this given your input of "New.York" could be:
str.split('.').collect { |s| s[0] }.join('.')
which would return 'N.Y'
Use this regex and you should only output the groups \1 and \2.
([a-zA-Z])[^.]*\.([a-zA-Z]).*?\b
DEMO
If you want to do a replacement you should use \1.\2
You could use the capital letters to dictate the regex match using something like this:
[15] pry(main)> str
=> "New.York"
[16] pry(main)> str.scan(/[A-Z]+/).join('.')
=> "N.Y"
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have a field that contains titles like "IT Professional" or "DB Administrator".
I want to display this in the middle of a sentence and so need to down-case. Unfortunately, this also downcases the acronyms and I end up with "Thanks for joining a community of it professionals".
A good start would be the solution mentioned by Grantovich below, i.e. specifying my acronyms in config/initializers/inflections.rb:
ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym "IT"
inflect.acronym "DB"
end
The problem with going this route is that firstly, I don't want to store them in lower case as suggested as part of the solution because they are titles and should be stored with capitals. Secondly, they are already defined in uppercase and it would be a bad idea to suddenly make them lower case.
Solution Found: Since I want the title to appear in the middle of a sentence, hence the need for lower case, I solved it by downcasing the title, constructing the sentence and then calling #humanize on that. Humanize will capitalize the first letter of the sentence and any defined acronyms.
If possible, I would store the strings as "IT professional", "DB administrator", etc. with all letters except for the acronyms already downcased. Then you can add your acronyms to the inflector and use #titleize to convert to title case when needed. In terms of edge cases and code maintenance burden, this is a better solution than writing your own code to do "selective downcasing".
If we assume that by acronym, you mean any word in your string that is made of 2 or more capitals in a row, then you could do something like this:
def smart_case(field)
field.to_s.split(' ').map { |word|
/[A-Z][A-Z]+/.match(word) ? word : word.downcase
}.join(' ')
end
This is an ugly way to do it but:
def format_me(str)
str.downcase!
#acronymn_words = ["IT Professional", "DB Administrator"]
#acronymn_words.each do |a|
if str.include? a.downcase
str.gsub!(a.downcase,a)
end
end
capitalize_next = true
str = str.split.map do |word|
if capitalize_next then word.capitalize! end
capitalize_next = word.end_with?(".","!","?")
word
end.join(" ")
end
This would be difficult to maintain unless you know the exact strings you are looking for but it will put out a correctly formatted sentence with the items you requested.
I would do this like that :
do_not_downcase = ["IT", "DB"] # Complete the list with your favourites words
res = ""
str.split(" ").each do |word|
if !do_not_downcase.include? word then
res += word.downcase + " "
else
res += word + " "
end
end
puts res
>welcome IT professionals