In Ruby, can I check if a string contains a letter without using regular expressions?

泄露秘密 提交于 2021-02-07 13:17:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!