Чи є алгоритм c # для синдуляризації - множини слова?


106

Чи є алгоритм c # для синдуляризації - множини слова (англійською мовою) чи існує бібліотека .net для цього (може бути також на різних мовах)?

Відповіді:


182

У вас також є System.Data.Entity.Design.PluralizationServices.PluralizationService .

ОНОВЛЕННЯ : Стара відповідь заслуговує на оновлення. Зараз також є Гуманізатор: https://github.com/MehdiK/Humanizer


2
Гммм, чи дозволяєте ви перерозподіляти або просто використовувати дизайнерський DLL? Я прошу це, бо знаю, що ліцензія на DevExpress забороняє перерозподіляти будь-які .design DLL.
Pierre-Alain Vigeant

58
Відкриття коду за допомогою ILSpy показує клас під назвою EnglishPluralizationService, у якому визначено безліч виняткових випадків та робить їх цікавими для читання. Мені особливо подобається "пневмонотрамікроскопічнийспілковолканоконіоз", який я вважаю, що весь час використовую в своїх моделях сутності ... 8o)
MrKWatkins,

7
Я можу здогадатися, як це додалося. Тестер подав помилку на розробник, кажучи, що це не працює на сказане слово. Дев це виправив. Обоє поділилися сміхом.
merlinbeard

2
@MrKWatkins Звучить більше як "supercalifragilisticexpialidocious"
Corstian Boerman

1
Гуманізатор - чудова рекомендація. Я, звичайно, реалізовував би, як сам 15%, перш ніж з'ясувати, що він існує.
Кейсі

18

Я можу це зробити на есперанто, без особливих випадків!

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

Для англійської мови було б корисно ознайомитись з правилами регулярного множини іменників , а також з неправильними множинами іменників . Є ціла стаття у Вікіпедії на англійській множині , яка також може мати корисну інформацію.


5
Ви повинні змусити його кидати, якщо ви переходите з дієсловом чи прислівником!
Тімві

1
@Matt: Звичайно, це підходить для називного випадку; Я вірю, що поширення цього методу на звинувачувальну справу є простим для проникливого читача.
Грег Хьюгілл

14

Більшість ORM мають удар, хоча вони, як правило, не є ідеальними. Я знаю, що в замку є клас Inflector, про який ви, мабуть, можете повозитися. Зробити це "ідеально" - це непросте завдання (англійська "правила" насправді не правила :)), тому це залежить, чи задоволений ви підходом "розумної здогадки".


З вашої пропозиції я шукав "Inflector" і виявив це andrewpeters.net/inflectornet, який, в основному, може бути таким самим із Замку один
Ронні

4
Насправді це не в основному однакове, його ідентичне.
Девід Пфеффер

12

Я обдурив Java - я хотів, щоб я могла створити правильний рядок для "Там було n щось (и)", тому я написав фол. мало перевантажений корисний метод:

static public String pluralize(int val, String sng) {
    return pluralize(val,sng,(sng+"s"));
    }

static public String pluralize(int val, String sng, String plu) {
    return (val+" "+(val==1 ? sng : plu)); 
    }

викликається так

System.out.println("There were "+pluralize(count,"something"));
System.out.println("You have broken "+pluralize(count,"knife","knives"));

Це охоплює лише невеликі розділи граматики, але вона не враховує таких слів, як вікторини, вечірки, половинки, миші, індекси тощо. Це хороший перший удар, але існує маса інших правил, які, ймовірно, повинні бути оброблені спочатку .
Jeremy S

4
@Jeremy: Чому б і ні ?: println ("Ви пройшли" + singularPlural (кількість, "вікторина", "вікторини") + "поки що")
Лоуренс Дол,

Я можу трактувати питання по-різному. Я думаю, що алгоритм повинен визначати форму множини без будь-якого натяку з боку розробника, тоді як ваш метод покладає на себе знати, що форма множини є на розробника.
Джеремі S

3
@Jeremy: Отже, ведучий "Я обдурив ..." - не здається, що є підставою для протистояння.
Лоуренс Дол,

1
Домовились. Я також вважаю, що надана інформація була корисною, і тому будь-яка нижченаведена пропозиція не надійшла від мене. Я взагалі не піддаюсь голосуванню за принципом "мотлоху одного чоловіка ...".
Джеремі S

10

Я створив крихітну бібліотеку для цього в .net (C #), що називається Pluralizer (не дивно).

Це призначено для роботи з повними пропозиціями, такими, як String.Format.

Це в основному працює так:

var target = new Pluralizer();
var str = "There {is} {_} {person}.";

var single = target.Pluralize(str, 1);
Assert.AreEqual("There is 1 person.", single);

// Or use the singleton if you're feeling dirty:
var several = Pluralizer.Instance.Pluralize(str, 47);
Assert.AreEqual("There are 47 people.", several);

Це також може зробити набагато більше, ніж це. Детальніше про це читайте на моєму блозі . Він також доступний в NuGet.



4
Так, ця бібліотека виконує лише окремі слова та лише іменники (хоча Pluralizer використовує цей клас всередині). Ця бібліотека полегшує написання цілих речень. Перегляньте мій блог, щоб отримати більше прикладів. Pluralizer.Instance.Pluralize ("{She} {is} to going | her | their відповідний} {home}.", 5)
Jay Querido

Shaun Wilson - Мій комп'ютер наразі є частинами. Я поспішаю повернути його назад і оновиться протягом дня або двох. Тим часом, nuget.org/packages?q=pluralizer
Jay Querido

8

Я збив один разом на основі плюралізатора Rails. Ви можете побачити мою публікацію в блозі тут або на Github тут

output = Formatting.Pluralization(100, "sausage"); 

3
Дякую, що поділились. Радий, що мені не потрібно було посилатися на іншу збірку.
hofnarwillie

1
Простий і красивий!, Але не потрапляє в утворювати форму однини функціональних
драм

5

Оскільки питання стосувалося C #, ось приємна варіація рішення Software Monkey (знову трохи "обман", але для мене дійсно найбільш практичний і багаторазовий спосіб зробити це):

    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;
    }

Використання полягає в наступному:

"Item".Pluralize(1) = "Item"
"Item".Pluralize(2) = "Items"

"Person".Pluralize(1, "People") = "Person"
"Person".Pluralize(2, "People") = "People"

3

Subsonic 3 має Inflectorклас, який мене вразив, перетворившись Personна People. Я зазирнув до джерела і виявив, що це, природно, трохи обманює список з твердим кодом, але це дійсно єдиний спосіб зробити це англійською мовою і як це роблять люди - ми пам’ятаємо однину і множину кожного слова і не просто застосовуємо правило . Оскільки до суміші не додати чоловічої / жіночої (/ нейтральної) форми, це набагато простіше.

Ось фрагмент:

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");

Це пояснює те, що деякі слова не мають множинних еквівалентів, як приклад обладнання. Як ви, напевно, можете сказати, це робить просту Regexзаміну за допомогою $ 1.

Оновлення:
Здається, що Subsonic Inflectorє непорушнимInflector класом Castle ActiveRecord !


2

Немало документації від MSDN про специфічне використання класу PluralizationService, тому тут є тестовий клас одиниць (NUnit) для показу базового використання. Зауважте, що внизу тестовий випадок, що показує, що послуга не є ідеальною, якщо мова йде про нестандартні форми множини.

[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
    }
}


1

Використання прикладної бази даних Northwind Microsoft:

 System.Data.Entity.Design.PluralizationServices.PluralizationService.CreateService(new System.Globalization.CultureInfo("en-US"));

Singularize не Singularize "Order_Details" Він повертає "Order_Details" з sкінцем. Яка робота навколо?


1
Це питання, а не відповідь на запитання ... але Pluralize () та Singularize () працюють лише зі словниковими словами. Існує спосіб додати слова за допомогою ICustomPluralizationMapping.AddWord, але, принаймні, для мене це було не дуже вдале рішення, коли у вас може бути багато нереальних слів, як кодові назви.
tordal

@tordal Дякую, саме до цього питання я прийшов
Чад
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.