Is there any algorithm in c# to singularize - pluralize a word?

前端 未结 11 1799
臣服心动
臣服心动 2020-12-07 10:55

Is there any algorithm in c# to singularize - pluralize a word (in english) or does exist a .net library to do this (may be also in different languages)?

相关标签:
11条回答
  • 2020-12-07 11:26

    Most ORMs have a stab at it, although they generally aren't perfect. I know Castle has it's Inflector Class you can probably poke around. Doing it "perfectly" isn't an easy task though (English "rules" aren't really rules :)), so it depends if you are happy with a "reasonable guess" approach.

    0 讨论(0)
  • 2020-12-07 11:27

    As the question was for C#, here is a nice variation on Software Monkey's solution (again a bit of a "cheat", but for me really the most practical and reusable way of doing this):

        public static string Pluralize(this string singularForm, int howMany)
        {
            return singularForm.Pluralize(howMany, singularForm + "s");
        }
    
        public static string Pluralize(this string singularForm, int howMany, string pluralForm)
        {
            return howMany == 1 ? singularForm : pluralForm;
        }
    

    The usage is as follows:

    "Item".Pluralize(1) = "Item"
    "Item".Pluralize(2) = "Items"
    
    "Person".Pluralize(1, "People") = "Person"
    "Person".Pluralize(2, "People") = "People"
    
    0 讨论(0)
  • 2020-12-07 11:28

    Subsonic 3 has an Inflector class which impressed me by turning Person into People. I peeked at the source and found it naturally cheats a little with a hardcoded list but that's really the only way of doing it in English and how humans do it - we remember the singular and plural of each word and don't just apply a rule. As there's not masculine/feminine(/neutral) to add to the mix it's a lot simpler.

    Here's a snippet:

    AddSingularRule("^(ox)en", "$1");
    AddSingularRule("(vert|ind)ices$", "$1ex");
    AddSingularRule("(matr)ices$", "$1ix");
    AddSingularRule("(quiz)zes$", "$1");
    
    AddIrregularRule("person", "people");
    AddIrregularRule("man", "men");
    AddIrregularRule("child", "children");
    AddIrregularRule("sex", "sexes");
    AddIrregularRule("tax", "taxes");
    AddIrregularRule("move", "moves");
    
    AddUnknownCountRule("equipment");
    

    It accounts for some words not having plural equivalents, like the equipment example. As you can probably tell it does a simple Regex replace using $1.

    Update:
    It appears Subsonic's Inflector is infact the Castle ActiveRecord Inflector class!

    0 讨论(0)
  • 2020-12-07 11:30

    You also have the System.Data.Entity.Design.PluralizationServices.PluralizationService.

    UPDATE: Old answer deserves update. There's now also Humanizer: https://github.com/MehdiK/Humanizer

    0 讨论(0)
  • 2020-12-07 11:32

    Not much documentation from MSDN on the specific usage of the PluralizationService class so here is a unit test class (NUnit) to show basic usage. Notice the odd test case at the bottom that shows the service isn't perfect when it comes to non-standard plural forms.

    [TestFixture]
    public class PluralizationServiceTests
    {
        [Test]
        public void Test01()
        {
            var service = PluralizationService.CreateService(CultureInfo.CurrentCulture);
    
            Assert.AreEqual("tigers", service.Pluralize("tiger"));
            Assert.AreEqual("processes", service.Pluralize("process"));
            Assert.AreEqual("fungi", service.Pluralize("fungus"));
    
            Assert.AreNotEqual("syllabi", service.Pluralize("syllabus")); // wrong pluralization
        }
    }
    
    0 讨论(0)
  • 2020-12-07 11:36

    I can do it for Esperanto, with no special cases!

    string plural(string noun) { return noun + "j"; }
    

    For English, it would be useful to become familiar with the rules for Regular Plurals of Nouns, as well as Irregular Plurals of Nouns. There is a whole Wikipedia article on the English plural, which may have some helpful information too.

    0 讨论(0)
提交回复
热议问题