media
media

Reputation: 135

Ruby RoR parsing a string upper

I'm new to ruby, I would like to parse each char from this string for example str = "Amdh#34HB!x" and get the result like this :

1) into string

"Upper : 3 Lower : 4 numbers : 2 special : 2"

2) stock results into variables

@Upper = 3
@Lower = 4
@numbers = 2
@special = 2

Any help please ?

Upvotes: 1

Views: 81

Answers (3)

Cary Swoveland
Cary Swoveland

Reputation: 110665

Here's a way to obtain the counts by making a single pass through the string, regardless of the number of character categories.

Code

CATS = { upper: /[[:upper:]]/, lower: /[[:lower:]]/,
         number: /[[:digit:]]/, special: /./ }

def count_character_types(str)
  str.each_char.with_object(CATS.keys.product([0]).to_h) do |c,h|
    k,_ = CATS.find { |k,r| c =~ r } 
    h[k] += 1
  end
end

Example

h = count_character_types("Amdh#34HB!x")
  #=> {:upper=>3, :lower=>4, :number=>2, :special=>2} 

Note that

CATS.keys.product([0]).to_h
  #=> {:upper=>0, :lower=>0, :number=>0, :special=>0}

Convert hash to a string

A hash may be a more useful return value than a string, but if you want a string, there's one more step:

h.map { |k,v| "#{k.to_s.capitalize} : #{v}" }.join(' ')
  #=> "Upper : 3 Lower : 2 Number : 2 : 4 Special" 

"Digit" would be a more accurate name for the key "Number".

Upvotes: 1

Bruno Vieira Costa
Bruno Vieira Costa

Reputation: 29

there are many ways to do this, the most didatic in my opinion is

str = gets.chomp # Here you get the string from user
@Upper = 0
@Lower = 0
@numbers = 0
@special = 0
for char in str.chars do
    if /[a-z]/=~ char then
        @Lower += 1
    elsif /[A-Z]/=~ char then
        @Upper += 1
    elsif /[0-9]/=~ char then
        @numbers += 1
    else
        @special += 1
    end
end
puts "Upper : #{@Upper} Lower : #{@Lower} numbers : #{@numbers} special : #{@special}"

Upvotes: 2

Matt Antonelli
Matt Antonelli

Reputation: 119

s = 'Amdh#34HB!x'

upper = s.scan(/[A-Z]/).count
lower = s.scan(/[a-z]/).count
numbers = s.scan(/[0-9]/).count
special = s.scan(/[^a-z0-9]/i).count

"Upper: #{upper} Lower: #{lower} Numbers: #{numbers} Special: #{special}"

#=> "Upper: 3 Lower: 4 Numbers: 2 Special: 2"

Upvotes: 2

Related Questions