Esiste un algoritmo in c # per singolarizzare - pluralizzare una parola?


106

Esiste un algoritmo in c # per singolarizzare - pluralizzare una parola (in inglese) o esiste una libreria .net per farlo (potrebbe essere anche in lingue diverse)?

Risposte:


182

Hai anche System.Data.Entity.Design.PluralizationServices.PluralizationService .

AGGIORNAMENTO : la vecchia risposta merita un aggiornamento. Ora c'è anche Humanizer: https://github.com/MehdiK/Humanizer


2
Hmmm sei autorizzato a ridistribuire, o semplicemente usare, una DLL di progettazione? Lo chiedo perché so che la licenza per DevExpress proibisce la ridistribuzione di qualsiasi DLL .design.
Pierre-Alain Vigeant

58
L'apertura del codice con ILSpy mostra una classe chiamata EnglishPluralizationService, che ha molti casi eccezionali definiti e rende la lettura interessante. Mi piace particolarmente la 'pneumonoultramicroscopicsilicovolcanoconiosis', che mi trovo a usare tutto il tempo nei miei modelli di entità ... 8o)
MrKWatkins

7
Posso immaginare come sia stato aggiunto. Un tester ha segnalato un bug sullo sviluppatore dicendo che non funziona per la parola detta. Dev ha risolto il problema. Entrambi hanno condiviso una risata.
Merlinbeard

2
@MrKWatkins suona più come 'supercalifragilisticexpialidocious'
Corstian Boerman

1
Humanizer è un'ottima raccomandazione. Ovviamente ne avevo implementato circa il 15% prima di scoprire che esisteva.
Casey

18

Posso farlo per l'esperanto, senza casi speciali!

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

Per l'inglese, sarebbe utile acquisire familiarità con le regole per i plurali regolari dei nomi , nonché per i plurali irregolari dei nomi . C'è un intero articolo di Wikipedia sul plurale inglese , che potrebbe contenere anche alcune informazioni utili.


5
Dovresti farlo lanciare se passi in un verbo o avverbio!
Timwi

1
@ Matt: ovviamente questo è appropriato per il caso nominativo; Confido che estendere questo metodo al caso accusativo sia semplice per un lettore astuto.
Greg Hewgill,

14

La maggior parte degli ORM ci prova, anche se generalmente non sono perfetti. So che Castle ha la sua classe Inflector che probabilmente puoi dare un'occhiata in giro. Farlo "perfettamente" non è un compito facile (le "regole" inglesi non sono realmente regole :)), quindi dipende se sei soddisfatto di un approccio "ragionevole".


Dal tuo suggerimento ho cercato "Inflector" e ho trovato questo andrewpeters.net/inflectornet che fondamentalmente potrebbe essere lo stesso di Castle
Ronnie,

4
In realtà non è fondamentalmente lo stesso, è identico.
David Pfeffer

12

Ho imbrogliato in Java: volevo essere in grado di produrre una stringa corretta per "C'erano n qualcosa", quindi ho scritto il foll. metodo di utilità poco sovraccarico:

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

invocato in questo modo

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

Questo copre solo una piccola sezione della grammatica, non tiene conto di parole come quiz, feste, metà, topi, indici, ecc. È un buon primo tentativo, ma ci sono molte altre regole che probabilmente dovrebbero essere elaborate per prime .
Jeremy S

4
@ Jeremy: Perché no ?: println ("Hai superato" + singularPlural (count, "quiz", "quiz") + "so far")
Lawrence Dol

Potrei interpretare la domanda in modo diverso. Penso che l'algoritmo dovrebbe determinare la forma plurale senza alcun suggerimento da parte dello sviluppatore, mentre il tuo metodo pone l'onere di sapere quale sia la forma plurale sullo sviluppatore.
Jeremy S

3
@ Jeremy: Quindi l'iniziale "Ho imbrogliato ..." non sembra giustificare un voto negativo.
Lawrence Dol,

1
Concordato. Penso anche che le informazioni fornite siano state utili, motivo per cui nessun voto negativo non è venuto da me. In generale, non offendo voti negativi, sulla falsariga del "spazzatura di un uomo ...".
Jeremy S

10

Ho creato una piccola libreria per questo in .net (C #), chiamata Pluralizer (non sorprende).

È pensato per funzionare con frasi complete, qualcosa come String.Format.

Fondamentalmente funziona in questo modo:

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

Può anche fare molto di più. Per saperne di più sul mio blog . È disponibile anche in NuGet.



4
Sì, quella libreria fa solo singole parole e solo nomi (anche se Pluralizer usa quella classe internamente). Questa libreria semplifica la scrittura di intere frasi. Dai un'occhiata al mio blog per ulteriori esempi. Pluralizer.Instance.Pluralize ("{She} {is} going to {her | their rispettivi} {home}.", 5)
Jay Querido

Shaun Wilson - Il mio computer è attualmente in parti. Mi affretto a ripristinarlo e lo aggiornerò entro un giorno o due. Nel frattempo, nuget.org/packages?q=pluralizer
Jay Querido

8

Ne ho creato uno in base al pluralizzatore di Rails. Puoi vedere il mio post sul blog qui o su GitHub qui

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

3
Grazie per la condivisione. Sono contento di non aver bisogno di fare riferimento a un altro assembly.
hofnarwillie

1
Semplice e bello !, ma manca la funzionalità Singularize
amd

5

Poiché la domanda era per C #, ecco una bella variazione sulla soluzione di Software Monkey (di nuovo un po 'un "trucco", ma per me davvero il modo più pratico e riutilizzabile per farlo):

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

L'utilizzo è il seguente:

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

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

3

Subsonic 3 ha una Inflectorclasse che mi ha impressionato trasformandomi Personin People. Ho sbirciato la fonte e ho scoperto che naturalmente inganna un po 'con un elenco codificato, ma questo è davvero l'unico modo per farlo in inglese e come lo fanno gli umani: ricordiamo il singolare e il plurale di ogni parola e non applichiamo solo una regola . Dato che non c'è maschile / femminile (/ neutro) da aggiungere al mix, è molto più semplice.

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

Rappresenta alcune parole che non hanno equivalenti plurali, come l'esempio dell'attrezzatura. Come probabilmente puoi dire, fa una semplice Regexsostituzione usando $ 1.

Aggiornamento:
sembra che Subsonic Inflectorsia la classe Castle ActiveRecordInflector !


2

Non c'è molta documentazione da MSDN sull'utilizzo specifico della classe PluralizationService, quindi ecco una classe di unit test (NUnit) per mostrare l'utilizzo di base. Notare lo strano caso di test in basso che mostra che il servizio non è perfetto quando si tratta di forme plurali non standard.

[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

Utilizzando il database di esempio Northwind di Microsoft:

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

Singularize non singularizza "Order_Details" Restituisce "Order_Details" con salla fine. Qual è il lavoro intorno?


1
Questa è una domanda, non una risposta a una domanda ... ma Pluralize () e Singularize () funzionano solo con le parole del dizionario. C'è un modo per aggiungere parole usando ICustomPluralizationMapping.AddWord, ma almeno per me non è stata una buona soluzione quando potresti avere molte parole non reali come i nomi in codice.
tordale

@tordal Grazie, questo è esattamente il motivo per cui sono arrivato a questa domanda
Chad
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.