The problem
I assume that the objective is to capitalize, for each word, all letters at even indices (the first letter of the word having index zero).
Here are two ways to do that. Both methods use String#gsub with a regular expression. Depending on requirements it may be necessary to change str.gsub...
to str.downcase.gsub...
for both methods.
Use a regular expression to match one- or two-characters strings, two if possible, and capitalize those strings.
def weirdcase(str)
str.gsub(/(?<=A| |[^ ]{2})[^ ]{1,2}/) { |s| s.capitalize }
end
weirdcase "this is a sentence for testing"
#=> "ThIs Is A SeNtEnCe FoR TeStInG"
The regular expression reads, "match one or two characters other than spaces, two if possible ([^ ]{1,2}
), that are immediately preceded by one of the following: the beginning of the string (A
), a space or two characters other than spaces. (?<=A| |[^ ]{2})
is a positive lookbehind.
s.capitalize
invokes the method String#capitalize on the match.
Use a cycling enumerator
def weirdcase(str)
enum = [:upcase, :downcase].cycle
str.gsub(/./) do |s|
if s == ' '
enum.rewind
' '
else
s.public_send(enum.next)
end
end
end
weirdcase "this is a sentence for testing"
#=> "ThIs Is A SeNtEnCe FoR TeStInG"
The regular expression /./
matches each character in the string.
See Array#cycle, Enumerator#rewind, Enumerator#next and Object#public_send.
Note the following.
enum = [:upcase, :downcase].cycle
#=> #<Enumerator: [:upcase, :downcase]:cycle>
enum.next
#=> :upcase
enum.next
#=> :downcase
enum.next
#=> :upcase
enum.rewind
#=> #<Enumerator: [:upcase, :downcase]:cycle>
enum.next
#=> :upcase
enum.next
#=> :downcase
... ad infinitum
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…