Packages

Singularize and pluralize english nouns.

Current section

Files

Jump to
inflectorex lib regexps.ex
Raw

lib/regexps.ex

defmodule Inflectorex.Regexps do
@singular_uninflected Application.get_env(:inflectorex,:singular_uniflected,[]) ++
[
~r/(?i)(^(?:.*[nrlm]ese))$/,
~r/(?i)(^(?:.*deer))$/,
~r/(?i)(^(?:.*fish))$/,
~r/(?i)(^(?:.*measles))$/,
~r/(?i)(^(?:.*ois))$/,
~r/(?i)(^(?:.*pox))$/,
~r/(?i)(^(?:.*sheep))$/,
~r/(?i)(^(?:.*ss))$/
]
@plural_uninflected Application.get_env(:inflectorex,:plural_uniflected,[]) ++
[
~r/(?i)(^(?:.*[nrlm]ese))$/,
~r/(?i)(^(?:.*deer))$/,
~r/(?i)(^(?:.*fish))$/,
~r/(?i)(^(?:.*measles))$/,
~r/(?i)(^(?:.*ois))$/,
~r/(?i)(^(?:.*pox))$/,
~r/(?i)(^(?:.*sheep))$/,
~r/(?i)(^(?:people))$/
]
@uninflected ~r/((?i)(^(?:Amoyese))$
|(?i)(^(?:bison))$
|(?i)(^(?:Borghese))$
|(?i)(^(?:bream))$
|(?i)(^(?:breeches))$
|(?i)(^(?:britches))$
|(?i)(^(?:buffalo))$
|(?i)(^(?:cantus))$
|(?i)(^(?:carp))$
|(?i)(^(?:chassis))$
|(?i)(^(?:clippers))$
|(?i)(^(?:cod))$
|(?i)(^(?:coitus))$
|(?i)(^(?:Congoese))$
|(?i)(^(?:contretemps))$
|(?i)(^(?:corps))$
|(?i)(^(?:debris))$
|(?i)(^(?:diabetes))$
|(?i)(^(?:djinn))$
|(?i)(^(?:eland))$
|(?i)(^(?:elk))$
|(?i)(^(?:equipment))$
|(?i)(^(?:Faroese))$
|(?i)(^(?:flounder))$
|(?i)(^(?:Foochowese))$
|(?i)(^(?:gallows))$
|(?i)(^(?:Genevese))$
|(?i)(^(?:Genoese))$
|(?i)(^(?:Gilbertese))$
|(?i)(^(?:graffiti))$
|(?i)(^(?:headquarters))$
|(?i)(^(?:herpes))$
|(?i)(^(?:hijinks))$
|(?i)(^(?:Hottentotese))$
|(?i)(^(?:information))$
|(?i)(^(?:innings))$
|(?i)(^(?:jackanapes))$
|(?i)(^(?:Kiplingese))$
|(?i)(^(?:Kongoese))$
|(?i)(^(?:Lucchese))$
|(?i)(^(?:mackerel))$
|(?i)(^(?:Maltese))$
|(?i)(^(?:.*?media))$
|(?i)(^(?:mews))$
|(?i)(^(?:moose))$
|(?i)(^(?:mumps))$
|(?i)(^(?:Nankingese))$
|(?i)(^(?:news))$
|(?i)(^(?:nexus))$
|(?i)(^(?:Niasese))$
|(?i)(^(?:Pekingese))$
|(?i)(^(?:Piedmontese))$
|(?i)(^(?:pincers))$
|(?i)(^(?:Pistoiese))$
|(?i)(^(?:pliers))$
|(?i)(^(?:Portuguese))$
|(?i)(^(?:proceedings))$
|(?i)(^(?:rabies))$
|(?i)(^(?:rice))$
|(?i)(^(?:rhinoceros))$
|(?i)(^(?:salmon))$
|(?i)(^(?:Sarawakese))$
|(?i)(^(?:scissors))$
|(?i)(^(?:sea[- ]bass))$
|(?i)(^(?:series))$
|(?i)(^(?:Shavese))$
|(?i)(^(?:shears))$
|(?i)(^(?:siemens))$
|(?i)(^(?:species))$
|(?i)(^(?:swine))$
|(?i)(^(?:testes))$
|(?i)(^(?:trousers))$
|(?i)(^(?:trout))$
|(?i)(^(?:tuna))$
|(?i)(^(?:Vermontese))$
|(?i)(^(?:Wenchowese))$
|(?i)(^(?:whiting))$
|(?i)(^(?:wildebeest))$
|(?i)(^(?:Yengeese))$)/mix
@plural_regexps Application.get_env(:inflectorex,:plural,[]) ++
[ {~r/(?i)(.*)\b((?:atlas))$/, "atlases"},
{~r/(?i)(.*)\b((?:beef))$/, "beefs"},
{~r/(?i)(.*)\b((?:brother))$/, "brothers"},
{~r/(?i)(.*)\b((?:cafe))$/, "cafes"},
{~r/(?i)(.*)\b((?:child))$/, "children"},
{~r/(?i)(.*)\b((?:cookie))$/, "cookies"},
{~r/(?i)(.*)\b((?:corpus))$/, "corpuses"},
{~r/(?i)(.*)\b((?:cow))$/, "cows"},
{~r/(?i)(.*)\b((?:ganglion))$/, "ganglions"},
{~r/(?i)(.*)\b((?:genie))$/, "genies"},
{~r/(?i)(.*)\b((?:genus))$/, "genera"},
{~r/(?i)(.*)\b((?:graffito))$/, "graffiti"},
{~r/(?i)(.*)\b((?:hoof))$/, "hoofs"},
{~r/(?i)(.*)\b((?:loaf))$/, "loaves"},
{~r/(?i)(.*)\b((?:man))$/, "men"},
{~r/(?i)(.*)\b((?:money))$/, "monies"},
{~r/(?i)(.*)\b((?:mongoose))$/, "mongooses"},
{~r/(?i)(.*)\b((?:move))$/, "moves"},
{~r/(?i)(.*)\b((?:mythos))$/, "mythoi"},
{~r/(?i)(.*)\b((?:niche))$/, "niches"},
{~r/(?i)(.*)\b((?:numen))$/, "numina"},
{~r/(?i)(.*)\b((?:occiput))$/, "occiputs"},
{~r/(?i)(.*)\b((?:octopus))$/, "octopuses"},
{~r/(?i)(.*)\b((?:opus))$/, "opuses"},
{~r/(?i)(.*)\b((?:ox))$/, "oxen"},
{~r/(?i)(.*)\b((?:penis))$/, "penises"},
{~r/(?i)(.*)\b((?:person))$/, "people"},
{~r/(?i)(.*)\b((?:sex))$/, "sexes"},
{~r/(?i)(.*)\b((?:soliloquy))$/, "soliloquies"},
{~r/(?i)(.*)\b((?:testis))$/, "testes"},
{~r/(?i)(.*)\b((?:trilby))$/, "trilbys"},
{~r/(?i)(.*)\b((?:turf))$/, "turfs"},
{~r/(?i)(.*)\b((?:potato))$/, "potatoes"},
{~r/(?i)(.*)\b((?:hero))$/, "heroes"},
{~r/(?i)(.*)\b((?:tooth))$/, "teeth"},
{~r/(?i)(.*)\b((?:goose))$/, "geese"},
{~r/(?i)(.*)\b((?:foot))$/, "feet"},
{~r/(?i)(s)tatus$/, "\\g{1}\\g{2}tatuses"},
{~r/(?i)(quiz)$/, "\\g{1}zes"},
{~r/(?i)^(ox)$/, "\\g{1}\\g{2}en"},
{~r/(?i)([m|l])ouse$/, "\\g{1}ice"},
{~r/(?i)(matr|vert|ind)(ix|ex)$/, "\\g{1}ices"},
{~r/(?i)(x|ch|ss|sh)$/, "\\g{1}es"},
{~r/(?i)([^aeiouy]|qu)y$/, "\\g{1}ies"},
{~r/(?i)(hive)$/, "\\1s"},
{~r/(?i)(?:([^f])fe|([lre])f)$/, "\\g{1}\\g{2}ves"},
{~r/(?i)sis$/, "ses"},
{~r/(?i)([ti])um$/, "\\g{1}a"},
{~r/(?i)(p)erson$/, "\\g{1}eople"}, {~r/(?i)(m)an$/, "\\g{1}en"},
{~r/(?i)(c)hild$/, "\\g{1}hildren"}, {~r/(?i)(buffal|tomat)o$/, "\\g{1}\\g{2}oes"},
{~r/(?i)(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$/,"\\g{1}i"},
{~r/(?i)us$/, "uses"},
{~r/(?i)(alias)$/, "\\g{1}es"},
{~r/(?i)(ax|cris|test)is$/, "\\g{1}es"},
{~r/s$/, "s"},
{~r/^$/, ""},
{~r/$/, "s"}
]
@singular_regexps Application.get_env(:inflectorex,:singular,[]) ++
[
{~r/(?i)(.*)\b((?:foes))$/, "foe"},
{~r/(?i)(.*)\b((?:waves))$/, "wave"},
{~r/(?i)(.*)\b((?:curves))$/, "curve"},
{~r/(?i)(.*)\b((?:atlases))$/, "atlas"},
{~r/(?i)(.*)\b((?:beefs))$/, "beef"},
{~r/(?i)(.*)\b((?:brothers))$/, "brother"},
{~r/(?i)(.*)\b((?:cafes))$/, "cafe"},
{~r/(?i)(.*)\b((?:children))$/, "child"},
{~r/(?i)(.*)\b((?:cookies))$/, "cookie"},
{~r/(?i)(.*)\b((?:corpuses))$/, "corpus"},
{~r/(?i)(.*)\b((?:cows))$/, "cow"},
{~r/(?i)(.*)\b((?:ganglions))$/, "ganglion"},
{~r/(?i)(.*)\b((?:genies))$/, "genie"},
{~r/(?i)(.*)\b((?:genera))$/, "genus"},
{~r/(?i)(.*)\b((?:graffiti))$/, "graffito"},
{~r/(?i)(.*)\b((?:hoofs))$/, "hoof"},
{~r/(?i)(.*)\b((?:loaves))$/, "loaf"},
{~r/(?i)(.*)\b((?:men))$/, "man"},
{~r/(?i)(.*)\b((?:monies))$/, "money"},
{~r/(?i)(.*)\b((?:mongooses))$/, "mongoose"},
{~r/(?i)(.*)\b((?:moves))$/, "move"},
{~r/(?i)(.*)\b((?:mythoi))$/, "mythos"},
{~r/(?i)(.*)\b((?:niches))$/, "niche"},
{~r/(?i)(.*)\b((?:numina))$/, "numen"},
{~r/(?i)(.*)\b((?:occiputs))$/, "occiput"},
{~r/(?i)(.*)\b((?:octopuses))$/, "octopus"},
{~r/(?i)(.*)\b((?:opuses))$/, "opus"},
{~r/(?i)(.*)\b((?:oxen))$/, "ox"},
{~r/(?i)(.*)\b((?:penises))$/, "penis"},
{~r/(?i)(.*)\b((?:people))$/, "person"},
{~r/(?i)(.*)\b((?:sexes))$/, "sex"},
{~r/(?i)(.*)\b((?:soliloquies))$/, "soliloquy"},
{~r/(?i)(.*)\b((?:testes))$/, "testis"},
{~r/(?i)(.*)\b((?:trilbys))$/, "trilby"},
{~r/(?i)(.*)\b((?:turfs))$/, "turf"},
{~r/(?i)(.*)\b((?:potatoes))$/, "potato"},
{~r/(?i)(.*)\b((?:heroes))$/, "hero"},
{~r/(?i)(.*)\b((?:teeth))$/, "tooth"},
{~r/(?i)(.*)\b((?:geese))$/, "goose"},
{~r/(?i)(.*)\b((?:feet))$/, "foot"},
{~r/eaus$/, "eau"},
{~r/(?i)(s)tatuses$/, "\\g{1}\\g{2}tatus"},
{~r/(?i)^(.*)(menu)s$/, "\\g{1}\\g{2}"},
{~r/(?i)(quiz)zes$/, "\\1"},
{~r/(?i)(matr)ices$/, "\\g{1}ix"},
{~r/(?i)(vert|ind)ices$/, "\\g{1}ex"},
{~r/(?i)^(ox)en/, "\\1"},
{~r/(?i)(alias)(es)*$/, "\\1"},
{~r/(?i)(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$/,"\\g{1}us"},
{~r/(?i)([ftw]ax)es/, "\\1"},
{~r/(?i)(cris|ax|test)es$/, "\\g{1}is"},
{~r/(?i)(shoe|slave)s$/, "\\1"},
{~r/(?i)(o)es$/, "\\1"},
{~r/ouses$/, "ouse"},
{~r/([^a])uses$/, "\\g{1}us"},
{~r/(?i)([m|l])ice$/, "\\g{1}ouse"},
{~r/(?i)(x|ch|ss|sh)es$/, "\\1"},
{~r/(?i)(m)ovies$/, "\\g{1}\\g{2}ovie"},
{~r/(?i)(s)eries$/, "\\g{1}\\g{2}eries"},
{~r/(?i)([^aeiouy]|qu)ies$/, "\\g{1}y"},
{~r/(?i)(tive)s$/, "\\1"},
{~r/(?i)([lre])ves$/, "\\g{1}f"},
{~r/(?i)([^fo])ves$/, "\\g{1}fe"},
{~r/(?i)(hive)s$/, "\\1"},
{~r/(?i)(drive)s$/, "\\1"},
{~r/(?i)(^analy)ses$/, "\\g{1}sis"},
{~r/(?i)(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/,"\\g{1}\\g{2}sis"},
{~r/(?i)([ti])a$/, "\\g{1}um"},
{~r/(?i)(p)eople$/, "\\g{1}\\g{2}erson"},
{~r/(?i)(m)en$/, "\\g{1}an"},
{~r/(?i)(c)hildren$/, "\\g{1}\\g{2}hild"},
{~r/(?i)(n)ews$/, "\\g{1}\\g{2}ews"},
{~r/^(.*us)$/, "\\1"},
{~r/(?i)s$/, ""},
]
def in_uniflectable?(word,:singular) do
in_uniflect?(word,@singular_uninflected) || Regex.match?(@uninflected,word)
end
def in_uniflectable?(word,:plural) do
in_uniflect?(word,@plural_uninflected) || Regex.match?(@uninflected,word)
end
defp in_uniflect?(word,set) do
case Enum.find(set,fn (regex) -> Regex.match?(regex,word) end) do
nil -> false
_ -> true
end
end
def pluralize(word) do
if in_uniflectable?(word,:plural) do
word
else
find_replace(word,@plural_regexps)
end
end
def singularize(word) do
if in_uniflectable?(word,:singular) do
word
else
find_replace(word,@singular_regexps)
end
end
defp find_replace(word,set) do
# will match to a pattern unless singular passed to singularize and plural
# passed to pluralize
case Enum.find(set,nil,fn {regex,_} -> Regex.match?(regex,word) end ) do
nil -> word # can't try any further lets return the same thing
{regex,repl} -> Regex.replace(regex,word,repl)
end
end
end