jbwilmoth
jbwilmoth

Reputation: 3

Ruby regex puncuation

I am having trouble writing this so that it will take a sentence as an argument and perform the translation on each word without affecting the punctuation.

I'd also like to continue using the partition method.

It would be nice if I could have it keep a quote together as well, such as:

"I said this", I said.

would be:

"I aidsay histay", I said.

def convert_sentence_pig_latin(sentence)
  p split_sentence = sentence.split(/\W/)
  pig_latin_sentence = []
  split_sentence.each do |word|
    if word.match(/^[^aeiou]+/x)
      pig_latin_sentence << word.partition(/^[^aeiou]+/x)[2] +  word.partition(/^[^aeiou]+/x)[1] + "ay"
    else
      pig_latin_sentence << word
    end
  end
  rejoined_pig_sentence = pig_latin_sentence.join(" ").downcase + "."
  p rejoined_pig_sentence.capitalize
end

convert_sentence_pig_latin("Mary had a little lamb.")

Upvotes: 0

Views: 73

Answers (2)

SoAwesomeMan
SoAwesomeMan

Reputation: 3396

# iterate over and replace regexp matches using gsub
def convert_sentence_pig_latin2(sentence)
  r = /^[^aeiou]+/i
  sentence.gsub(/"([^"]*)"/m) {|x| x.gsub(/\w+/) {|y| y =~ r ? "#{y.partition(r)[2]}#{y.partition(r)[1]}ay" : y}}
end
puts convert_sentence_pig_latin2('"I said this", I said.')

# define instance method: String#to_pl
class String
  R = Regexp.new '^[^aeiou]+', true # => /^[^aeiou]+/i
  def to_pl
    self.gsub(/"([^"]*)"/m) {|x| x.gsub(/\w+/) {|y| y =~ R ? "#{y.partition(R)[2]}#{y.partition(R)[1]}ay" : y}}
  end
end
puts '"I said this", I said.'.to_pl

sources:

http://www.ruby-doc.org/core-2.1.0/Regexp.html

http://ruby-doc.org/core-2.0/String.html#method-i-gsub

Upvotes: 0

smathy
smathy

Reputation: 27961

Your main problem is that [^aeiou] matches every character outside that range, including spaces, commas, quotation marks, etc.

If I were you, I'd use a positive match for consonants, ie. [b-df-hj-np-tv-z] I would also put that regex in a variable, so you're not having to repeat it three times.

Also, in case you're interested, there's a way to make your convert_sentence_pig_latin method a single gsub and it will do the whole sentence in one pass.

Update

...because you asked...

sentence.gsub( /\b([b-df-hj-np-tv-z])(\w+)/i ) { "#{$2}#{$1}ay" }

Upvotes: 1

Related Questions