英単語の単数形を複数形にする
暇だったので、Githubを見ていたら、Rubyでは標準機能で英単語の単数形を複数形にする機能があると知りました。
へ~。
person→peopleとか。
wolf→wolvesとか。
覚えたな~。
などと中学校の英語の授業を思い出して懐かしくなりながら。
さてと。
Ruby2CSharp
Rubyは読めないのですが、正規表現は100行ほどなので、それならC#に移植しておいたらどうだろう。
ちょうどエクステンションの勉強中でもあるし。
移植!
ということで、移植してみました。
Rubyの正規表現では、指定範囲を引用するのに「\」を使うのですが、C#では「$」を使います。
/iの意味がわからなかったのでオミット。
/もなくしちゃいました。いいのかな。ま、いいか。
using System.Text.RegularExpressions;
public static class StringExtensions
{
public static string Inflections(this string value)
{
var inflect = value;
inflect = Regex.Replace(inflect, "s$", "s");
inflect = Regex.Replace(inflect, "^(ax|test)is$", "$1es");
inflect = Regex.Replace(inflect, "(octop|vir)us$", "$1i");
inflect = Regex.Replace(inflect, "(octop|vir)i$", "$1i");
inflect = Regex.Replace(inflect, "(alias|status)$", "$1es");
inflect = Regex.Replace(inflect, "(bu)s$", "$1ses");
inflect = Regex.Replace(inflect, "(buffal|tomat)o$", "$1oes");
inflect = Regex.Replace(inflect, "([ti])um$", "$1a");
inflect = Regex.Replace(inflect, "([ti])a$", "$1a");
inflect = Regex.Replace(inflect, "sis$", "ses");
inflect = Regex.Replace(inflect, "(?:([^f])fe|([lr])f)$", "$1$2ves");
inflect = Regex.Replace(inflect, "(hive)$", "$1s");
inflect = Regex.Replace(inflect, "([^aeiouy]|qu)y$", "$1ies");
inflect = Regex.Replace(inflect, "(x|ch|ss|sh)$", "$1es");
inflect = Regex.Replace(inflect, "(matr|vert|ind)(?:ix|ex)$", "$1ices");
inflect = Regex.Replace(inflect, "^(m|l)ouse$", "$1ice");
inflect = Regex.Replace(inflect, "^(m|l)ice$", "$1ice");
inflect = Regex.Replace(inflect, "^(ox)$", "$1en");
inflect = Regex.Replace(inflect, "^(oxen)$", "$1");
inflect = Regex.Replace(inflect, "(quiz)$", "$1zes");
inflect = inflect
.Replace("person", "people")
.Replace("man", "men")
.Replace("child", "children")
//.Replace("sex", "sexes")
.Replace("move", "moves")
.Replace("zombie", "zombies");
if (inflect == value) inflect += "s";
return inflect;
}
//https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/activesupport/lib/active_support/inflections.rb
ついでにテストも勉強中なので、テストも作ってみました。
テスト通ったから、こんな感じなのでしょうか。
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Tool.Tests
{
[TestClass()]
public class MainWindowTests
{
[TestMethod()]
public void InflectionsTest()
{
Assert.AreEqual("wolves", "wolf".Inflections());
Assert.AreEqual("apples", "apple".Inflections());
Assert.AreEqual("gifts", "gift".Inflections());
Assert.AreEqual("boxes", "box".Inflections());
Assert.AreEqual("people", "person".Inflections());
Assert.AreEqual("men", "man".Inflections());
Assert.AreEqual("women", "woman".Inflections());
Assert.AreEqual("children", "child".Inflections());
Assert.AreEqual("sexes", "sex".Inflections());
Assert.AreEqual("zombies", "zombie".Inflections());
}
}
}