Extracting vowels and consonants using regular expression

D

Dondi

I am trying to parse a string and extract all vowels and consonants
into two separate substrings. However, I can't get my solution to
work. Any pointers are appreciated. Here is the approach I am using:

1) Extended the String Class with the following methods:

class String
def vowels
self.scan(/[aeiou]|(?![aeiou])y(?![aeiou])/i)
end

def consonants
self.scan(/![aeiou]|(?=[aeiou])y(?=[aeiou])/i)
end
end

2) Invoke the methods:

test_paragraph = "Mary had a little lamb"
@vowel_sub_str = test_paragraph.vowels
@consonant_sub_str = test_paragraph.consonants

However, the result is just two empty strings. I believe the problem
is in the regular expression, but I can't figure out just where. Any
ideas/pointers are appreciated.

Thanks.
 
S

Stefano Crocco

Alle Saturday 02 February 2008, Dondi ha scritto:
I am trying to parse a string and extract all vowels and consonants
into two separate substrings. However, I can't get my solution to
work. Any pointers are appreciated. Here is the approach I am using:

1) Extended the String Class with the following methods:

class String
def vowels
self.scan(/[aeiou]|(?![aeiou])y(?![aeiou])/i)
end

def consonants
self.scan(/![aeiou]|(?=[aeiou])y(?=[aeiou])/i)
end
end

2) Invoke the methods:

test_paragraph = "Mary had a little lamb"
@vowel_sub_str = test_paragraph.vowels
@consonant_sub_str = test_paragraph.consonants

However, the result is just two empty strings. I believe the problem
is in the regular expression, but I can't figure out just where. Any
ideas/pointers are appreciated.

Thanks.

A simple (but I fear not too efficient) way is:

class String

def vowels
gsub(/[^aeiou]/, '')
end

def consonants
gsub(/[aeiou]/, '')
end

end

Stefano
 
R

Robert Dober

A simple (but I fear not too efficient) way is:
Not sure if OP excluded non letters from the input
class String

def vowels
gsub(/[^aeiou]/, '')
end

def consonants
gsub(/[aeiou]/, '')
end

end

Stefano
This shall do it in one run, quite complicated code, interested if
something more elegant can be found.
class String
def v_c
each_char.inject(["",""]){ |r, c|
case c
when /[aeiouy]/i
[r.first << c, r.last ]
when /[^a-z]/i
r
else
[r.first, r.last << c ]
end
}
end
end

HTH
Robert
 
C

Corey Haines

[Note: parts of this message were removed to make it a legal post.]

Elegant? I don't know, but I kind of like it. :)

"corey".split(//).partition { |x| "aeiouAEIOU"[x] }

returns

=> [["o", "e"], ["c", "r", "y"]]

irb(main):006:0> "corey haines".split(//).partition { |x| "aeiouAEIOU"[x] }
=> [["o", "e", "a", "i", "e"], ["c", "r", "y", " ", "h", "n", "s"]]

you might want to skip spaces


-Corey



A simple (but I fear not too efficient) way is:
Not sure if OP excluded non letters from the input
class String

def vowels
gsub(/[^aeiou]/, '')
end

def consonants
gsub(/[aeiou]/, '')
end

end

Stefano
This shall do it in one run, quite complicated code, interested if
something more elegant can be found.
class String
def v_c
each_char.inject(["",""]){ |r, c|
case c
when /[aeiouy]/i
[r.first << c, r.last ]
when /[^a-z]/i
r
else
[r.first, r.last << c ]
end
}
end
end

HTH
Robert
 
R

Robert Dober

Elegant? I don't know, but I kind of like it. :)

"corey".split(//).partition { |x| "aeiouAEIOU"[x] }

returns

=> [["o", "e"], ["c", "r", "y"]]

irb(main):006:0> "corey haines".split(//).partition { |x| "aeiouAEIOU"[x] }
=> [["o", "e", "a", "i", "e"], ["c", "r", "y", " ", "h", "n", "s"]]

you might want to skip spaces


-Corey
Excellent Corey, allow me to make it fit *any* string, I still have
not seen any statement that we are treating letters only ;)

"cor4ey ha2ines".scan(/[a-z]/i).join.each_char.partition { |x| "aeiouAEIOU"[x] }

Robert
 
C

Corey Haines

[Note: parts of this message were removed to make it a legal post.]

Sweet! I like pulling the numbers out, but I get this in irb

irb(main):001:0> "cor4ey ha2ines".scan(/[a-z]/i).join.each_char.partition {
|x| "aeiouAEIOU"[x] }
NoMethodError: undefined method `each_char' for "coreyhaines":String

Why not use split(//) instead of each_char?


Elegant? I don't know, but I kind of like it. :)

"corey".split(//).partition { |x| "aeiouAEIOU"[x] }

returns

=> [["o", "e"], ["c", "r", "y"]]

irb(main):006:0> "corey haines".split(//).partition { |x| "aeiouAEIOU"[x] }
=> [["o", "e", "a", "i", "e"], ["c", "r", "y", " ", "h", "n", "s"]]

you might want to skip spaces


-Corey
Excellent Corey, allow me to make it fit *any* string, I still have
not seen any statement that we are treating letters only ;)

"cor4ey ha2ines".scan(/[a-z]/i).join.each_char.partition { |x|
"aeiouAEIOU"[x] }

Robert
 
C

Corey Haines

[Note: parts of this message were removed to make it a legal post.]

:) Cool. I wasn't sure exactly how to do that. Now I do! And, in the words
of one of my personal favorite philosophers, "Knowing is half the battle."

"cor4ey ha2ines".scan(/[a-z]/i).join.each_char.partition { |x|
"aeiouAEIOU"[x] }
and some golfing

{ |x| /[aeiou]/i =~ x }

R.
 
C

Corey Haines

[Note: parts of this message were removed to make it a legal post.]

Okay. Sounds good. I'm still on 1.8.

Thanks for the ideas.

-Corey
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top