问题
I'm using Rails 5. I want to know if a varaible (which you can assume is a String) contains at least one letter (upper case or lower case). However, I don't want to use regular expressions (I've noticed if the encoding is not UTF-8, regular expressiosn tend to crash). So I'm wondering how I can check if a string hast at least one letter.
THis doesn't work
input.downcase.include?("abcdefghijklmnopqrstuvwxyz")
回答1:
Try this
str.count("a-zA-Z") > 0
The count
function accepts character sets as argument.
This might still fail with ArgumentError: invalid byte sequence in UTF-8
though. If your input is invalid there is likely no way around fixing the encoding.
NB, this scans the entire string, but so does downcase
. For a performance benchmark see Eric's answer, performance varies a lot between worst case and best case scenario. As always though, readability comes before premature optimization.
回答2:
Code
You could use :
lowercase = ('a'..'z')
uppercase = ('A'..'Z')
input.each_char.any?{ |char| lowercase.cover?(char) || uppercase.cover?(char) }
It uses Range#cover?, which is faster than Range#include? because it just checks that char >= 'a'
and char <= 'z'
.
Performance
With a worst-case scenario (huge String without letters "1#+~?5()=[" * 10_000
) :
Running each test 8 times. Test will take about 9 seconds.
_akuhn is faster than _mudasobwa by 2.0x ± 0.01
_mudasobwa is faster than _cary by 14x ± 0.1
_cary is faster than _eric_duminil by 10.5x ± 0.1
With the tail of an mp3 file (600kb) :
Running each test 2048 times. Test will take about 7 minutes.
_cary is faster than _eric_duminil by 12x ± 1.0
_eric_duminil is faster than _mudasobwa by 430x ± 10.0
_mudasobwa is faster than _akuhn by 3x ± 0.1
It's interesting to see the results vary so much.
回答3:
checker = lambda do |input|
"abcdefghijklmnopqrstuvwxyz".split('').any? &input.downcase.method(:include?)
end
checker.('3F3')
#⇒ true
checker.('42')
#⇒ false
来源:https://stackoverflow.com/questions/41536289/in-ruby-can-i-check-if-a-string-contains-a-letter-without-using-regular-express