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

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


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.


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”.


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

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.



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

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"

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 !


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


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?


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.