# by activesupport/lib/active_support/inflector.rb @@singular = [] def add_singular(rule, replace) @@singular << [rule, replace] end add_singular(/s$/i, '') add_singular(/(n)ews$/i, '\1ews') add_singular(/([ti])a$/i, '\1um') add_singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis') add_singular(/(^analy)ses$/i, '\1sis') add_singular(/([^f])ves$/i, '\1fe') add_singular(/(hive)s$/i, '\1') add_singular(/(tive)s$/i, '\1') add_singular(/([lr])ves$/i, '\1f') add_singular(/([^aeiouy]|qu)ies$/i, '\1y') add_singular(/(s)eries$/i, '\1eries') add_singular(/(m)ovies$/i, '\1ovie') add_singular(/(x|ch|ss|sh)es$/i, '\1') add_singular(/([m|l])ice$/i, '\1ouse') add_singular(/(bus)es$/i, '\1') add_singular(/(o)es$/i, '\1') add_singular(/(shoe)s$/i, '\1') add_singular(/(cris|ax|test)es$/i, '\1is') add_singular(/(octop|vir)i$/i, '\1us') add_singular(/(alias|status)es$/i, '\1') add_singular(/^(ox)en/i, '\1') add_singular(/(vert|ind)ices$/i, '\1ex') add_singular(/(matr)ices$/i, '\1ix') add_singular(/(quiz)zes$/i, '\1') # The reverse of +pluralize+, returns the singular form of a word in a string. # # Examples: # "posts".singularize # => "post" # "octopi".singularize # => "octopus" # "sheep".singluarize # => "sheep" # "word".singluarize # => "word" # "the blue mailmen".singularize # => "the blue mailman" # "CamelOctopi".singularize # => "CamelOctopus" def singularize(word) result = word.to_s.dup @@singular.each { |(rule, replacement)| break if result.gsub!(rule, replacement) } result end