Czy jest jakiś algorytm w języku C # do wyróżniania - liczby mnogiej słowa?

106

Czy w języku C # jest jakiś algorytm do wyróżniania - pluralizuj słowo (w języku angielskim) lub czy istnieje biblioteka .net do tego celu (może być również w różnych językach)?

Ronnie
źródło

Odpowiedzi:

182

Masz również System.Data.Entity.Design.PluralizationServices.PluralizationService .

AKTUALIZACJA : Stara odpowiedź zasługuje na aktualizację. Jest teraz także Humanizer: https://github.com/MehdiK/Humanizer

Daniel
źródło
2
Hmmm, czy pozwalacie na redystrybucję, czy po prostu używanie biblioteki Design DLL? Pytam, ponieważ wiem, że licencja na DevExpress zabrania redystrybucji jakiejkolwiek biblioteki DLL .design.
Pierre-Alain Vigeant
58
Otwarcie kodu za pomocą ILSpy pokazuje klasę o nazwie EnglishPluralizationService, która ma wiele wyjątkowych przypadków zdefiniowanych w programie i sprawia, że ​​jest to interesująca lektura. Szczególnie podoba mi się „pneumonoultramicroscopicsilicovolcanoconiosis”, którą używam cały czas w moich modelach
bytów
7
Domyślam się, jak to zostało dodane. Tester zgłosił błąd do programisty, mówiąc, że nie działa dla tego słowa. Dev to naprawił. Obaj się roześmiali.
merlinbeard
2
@MrKWatkins Brzmi bardziej jak „supercalifragilisticexpialidocious”
Corstian Boerman
1
Humanizator to świetna rekomendacja. Oczywiście sam zaimplementowałem około 15%, zanim dowiedziałem się, że istnieje.
Casey
18

Mogę to zrobić dla esperanta, bez specjalnych przypadków!

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

W przypadku języka angielskiego przydatne byłoby zapoznanie się z regułami dotyczącymi zwykłej liczby mnogiej rzeczowników oraz nieregularnej liczby mnogiej rzeczowników . Istnieje cały artykuł w Wikipedii dotyczący angielskiej liczby mnogiej , który może również zawierać przydatne informacje.

Greg Hewgill
źródło
5
Powinieneś sprawić, by rzucił, jeśli podasz czasownik lub przysłówek!
Timwi,
1
@Matt: Oczywiście jest to właściwe dla mianownika; Ufam, że rozszerzenie tej metody na biernik jest proste dla bystrego czytelnika.
Greg Hewgill
14

Większość ORMów ma w tym coś wspólnego, chociaż generalnie nie są doskonałe. Wiem, że Castle ma swoją klasę Inflector, którą prawdopodobnie możesz poszperać . Jednak zrobienie tego „perfekcyjnie” nie jest łatwym zadaniem (angielskie „zasady” nie są tak naprawdę regułami :)), więc zależy to od tego, czy jesteś zadowolony z podejścia opartego na „rozsądnym przypuszczeniu”.

Steven Robbins
źródło
Zgodnie z twoją sugestią wyszukałem „Inflector” i znalazłem ten andrewpeters.net/inflectornet, który powinien być w zasadzie taki sam jak Castle
Ronnie
4
Właściwie to nie jest w zasadzie to samo, jest identyczne.
David Pfeffer
12

Oszukiwałem w Javie - chciałem być w stanie stworzyć poprawny ciąg znaków dla "Nie było czegoś", więc napisałem foll. mało przeciążona metoda narzędziowa:

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

wywołane w ten sposób

System.out.println("There were "+pluralize(count,"something"));
System.out.println("You have broken "+pluralize(count,"knife","knives"));
Lawrence Dol
źródło
Obejmuje to tylko małe sekcje gramatyki, ale nie uwzględnia słów takich jak quizy, imprezy, połówki, myszy, indeksy itp. To dobry pierwszy krok, ale jest wiele innych reguł, które prawdopodobnie powinny zostać przetworzone jako pierwsze .
Jeremy S
4
@Jeremy: Dlaczego nie ?: println ("Zdałeś" + singularPlural (count, "quiz", "quizy") + "do tej pory")
Lawrence Dol
Mogę inaczej zinterpretować to pytanie. Myślę, że algorytm powinien określać liczbę mnogą bez żadnej wskazówki od programisty, podczas gdy twoja metoda nakłada na programistę obowiązek poznania formy liczby mnogiej.
Jeremy S
3
@Jeremy: Stąd „I cheated ...” prowadzi - nie wydaje się uzasadniać negatywnego głosu.
Lawrence Dol
1
Zgoda. Uważam również, że podane informacje były przydatne, dlatego żaden głos przeciw nie pochodzi ode mnie. Generalnie nie głosuję przeciw, na wzór „śmieci jednego człowieka…”.
Jeremy S
10

Stworzyłem do tego małą bibliotekę w .net (C #), nazwaną Pluralizer (nic dziwnego).

Jest przeznaczony do pracy z pełnymi zdaniami, podobnie jak w przypadku String.Format.

Zasadniczo działa to tak:

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

Może też zrobić o wiele więcej. Przeczytaj więcej na ten temat na moim blogu . Jest również dostępny w NuGet.

Jay Querido
źródło
Czy są jakieś przewagi nad System.Data.Entity.Design.PluralizationServices.PluralizationService ?
John Saunders,
4
Tak, ta biblioteka obsługuje tylko pojedyncze słowa i tylko rzeczowniki (chociaż Pluralizer używa tej klasy wewnętrznie). Ta biblioteka ułatwia pisanie całych zdań. Więcej przykładów znajdziesz na moim blogu. Pluralizer.Instance.Pluralize („{She} {is} going to {her | their respond} {home}.”, 5)
Jay Querido
Shaun Wilson - Mój komputer jest obecnie w częściach. Pędzę, aby go przywrócić i zaktualizuję w ciągu jednego lub dwóch dni. W międzyczasie nuget.org/packages?q=pluralizer
Jay Querido
8

Zrobiłem jeden razem w oparciu o pluralizator Rails. Możesz zobaczyć mój post na blogu tutaj lub na github tutaj

output = Formatting.Pluralization(100, "sausage"); 
Matt Grande
źródło
3
Dzięki za udostępnienie. Cieszę się, że nie musiałem odwoływać się do innego zestawu.
hofnarwillie
1
Prosty i piękny !, ale pomija funkcjonalność Singularize
amd
5

Ponieważ pytanie dotyczyło C #, oto fajna odmiana rozwiązania Software Monkey (znowu trochę "oszustwa", ale dla mnie naprawdę najbardziej praktyczny i wielokrotnego użytku):

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

Sposób użycia jest następujący:

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

"Person".Pluralize(1, "People") = "Person"
"Person".Pluralize(2, "People") = "People"
Zaid Masud
źródło
3

Subsonic 3 ma Inflectorklasę, która zrobiła na mnie wrażenie, zmieniając się Personw People. Zerknąłem na źródło i odkryłem, że naturalnie trochę oszukuje z zakodowaną listą, ale to naprawdę jedyny sposób, aby to zrobić po angielsku i jak to robią ludzie - pamiętamy liczbę pojedynczą i mnogą każdego słowa i nie stosujemy tylko reguły . Ponieważ nie ma męskiego / kobiecego (/ neutralnego), aby dodać do mieszanki, jest to o wiele prostsze.

Oto fragment:

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

Wynika z tego, że niektóre słowa nie mają odpowiedników w liczbie mnogiej, jak przykład wyposażenia. Jak zapewne możesz powiedzieć, robi to prosteRegex zamianę za pomocą 1 $.

Aktualizacja:
Wygląda na Inflectorto, że Subsonic ma wpływ na klasę Castle ActiveRecordInflector !

Chris S.
źródło
2

Niewiele dokumentacji z MSDN na temat konkretnego użycia klasy PluralizationService, więc oto klasa testów jednostkowych (NUnit), aby pokazać podstawowe użycie. Zwróć uwagę na dziwny przypadek testowy na dole, który pokazuje, że usługa nie jest idealna, jeśli chodzi o niestandardowe formy liczby mnogiej.

[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
    }
}
Ryan Rodemoyer
źródło
1

Korzystanie z przykładowej bazy danych Northwind firmy Microsoft:

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

Singularize nie Singularize „Order_Details” Zwraca „Order_Details” z skońcówką. Jaka jest ta praca?

RandallTo
źródło
1
To jest pytanie, a nie odpowiedź na pytanie ... ale Pluralize () i Singularize () działają tylko ze słowami ze słownika. Istnieje sposób na dodawanie słów za pomocą ICustomPluralizationMapping.AddWord, ale przynajmniej dla mnie nie było to zbyt dobre rozwiązanie, gdy możesz mieć wiele nierzeczywistych słów, takich jak nazwy kodowe.
tordal
@tordal Dziękuję, właśnie po to przyszedłem na to pytanie
Czad