¿Hay algún algoritmo en c # para singularizar - pluralizar una palabra?

106

¿Existe algún algoritmo en c # para singularizar - pluralizar una palabra (en inglés) o existe una biblioteca .net para hacer esto (puede estar también en diferentes idiomas)?

Ronnie
fuente

Respuestas:

182

También tiene System.Data.Entity.Design.PluralizationServices.PluralizationService .

ACTUALIZACIÓN : La respuesta anterior merece una actualización. Ahora también hay Humanizer: https://github.com/MehdiK/Humanizer

Daniel
fuente
2
Hmmm, ¿está permitido redistribuir, o simplemente usar, una DLL de diseño? Lo pregunto porque sé que la licencia de DevExpress prohíbe la redistribución de cualquier DLL .design.
Pierre-Alain Vigeant
58
Al abrir el código con ILSpy, se muestra una clase llamada EnglishPluralizationService, que tiene muchos casos excepcionales definidos y resulta en una lectura interesante. Me gusta particularmente la 'pneumonoultramicroscopicsilicovolcanoconiosis', que me encuentro usando todo el tiempo en mis modelos de entidad ... 8o)
MrKWatkins
7
Puedo adivinar cómo se agregó eso. Un probador presentó un error en el desarrollador diciendo que no funciona para dicha palabra. Dev lo arregló. Ambos compartieron una risa.
merlinbeard
2
@MrKWatkins Suena más como 'supercalifragilisticexpialidocious'
Corstian Boerman
1
Humanizer es una gran recomendación. Por supuesto, yo mismo lo implementé como el 15% antes de descubrir que existía.
Casey
18

Puedo hacerlo para Esperanto, ¡sin casos especiales!

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

Para el inglés, sería útil familiarizarse con las reglas para Plurales regulares de sustantivos , así como Plurales irregulares de sustantivos . Hay un artículo completo de Wikipedia sobre el plural en inglés , que también puede tener información útil.

Greg Hewgill
fuente
5
¡Deberías hacerlo tirar si pasas un verbo o adverbio!
Timwi
1
@Matt: Por supuesto que esto es apropiado para el caso nominativo; Confío en que extender este método al caso acusativo sea sencillo para un lector astuto.
Greg Hewgill
14

La mayoría de los ORM lo intentan, aunque generalmente no son perfectos. Sé que Castle tiene su clase Inflector que probablemente puedas hurgar . Sin embargo, hacerlo "perfectamente" no es una tarea fácil (las "reglas" en inglés no son realmente reglas :)), por lo que depende de si está satisfecho con un enfoque de "conjetura razonable".

Steven Robbins
fuente
A partir de su sugerencia, busqué "Inflector" y encontré este andrewpeters.net/inflectornet que básicamente debería ser el mismo que el de Castle
Ronnie
4
En realidad, no es básicamente lo mismo, es idéntico.
David Pfeffer
12

Hice trampa en Java: quería poder producir una cadena correcta para "No había n algo (s)", así que escribí lo siguiente. método de utilidad poco sobrecargado:

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

invocado así

System.out.println("There were "+pluralize(count,"something"));
System.out.println("You have broken "+pluralize(count,"knife","knives"));
Lawrence Dol
fuente
Sin embargo, esto solo cubre una pequeña sección de la gramática, no tiene en cuenta palabras como cuestionarios, fiestas, mitades, ratones, índices, etc. Es un buen primer intento, pero hay muchas otras reglas que probablemente deberían procesarse primero .
Jeremy S
4
@Jeremy: ¿Por qué no ?: println ("Has aprobado" + singularPlural (cuenta, "cuestionario", "cuestionarios") + "hasta ahora")
Lawrence Dol
Podría estar interpretando la pregunta de manera diferente. Creo que el algoritmo debería determinar la forma plural sin ninguna pista por parte del desarrollador, mientras que su método pone la responsabilidad de saber cuál es la forma plural en el desarrollador.
Jeremy S
3
@Jeremy: Por lo tanto, el "Hice trampas ..." no parece justificar un voto negativo.
Lawrence Dol
1
Convenido. También creo que la información proporcionada fue útil, por lo que ningún voto negativo provino de mí. No voto en contra en general, en la línea de "la basura de un hombre ...".
Jeremy S
10

He creado una pequeña biblioteca para esto en .net (C #), llamada Pluralizer (como era de esperar).

Está destinado a funcionar con oraciones completas, algo como String.Format.

Básicamente funciona así:

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

También puede hacer mucho más que eso. Lea más sobre esto en mi blog . También está disponible en NuGet.

Jay Querido
fuente
4
Sí, esa biblioteca solo tiene palabras sueltas y solo sustantivos (aunque Pluralizer usa esa clase internamente). Esta biblioteca facilita la escritura de oraciones completas. Eche un vistazo a mi blog para ver más ejemplos. Pluralizer.Instance.Pluralize ("{Ella} {va} a {su | su respectiva} {casa}.", 5)
Jay Querido
Shaun Wilson - Mi computadora está actualmente en partes. Me apresuro a recuperarlo y lo actualizaré en uno o dos días. Mientras tanto, nuget.org/packages?q=pluralizer
Jay Querido
8

Batí uno juntos basado en el pluralizador Rails. Puedes ver la publicación de mi blog aquí , o en github aquí.

output = Formatting.Pluralization(100, "sausage"); 
Matt Grande
fuente
3
Gracias por compartir. Me alegro de no necesitar hacer referencia a otra asamblea.
hofnarwillie
1
¡Simple y hermoso !, pero echa de menos la funcionalidad Singularize
amd
5

Como la pregunta era para C #, aquí hay una buena variación de la solución de Software Monkey (de nuevo un poco "trampa", pero para mí es la forma más práctica y reutilizable de hacer esto):

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

El uso es el siguiente:

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

"Person".Pluralize(1, "People") = "Person"
"Person".Pluralize(2, "People") = "People"
Zaid Masud
fuente
3

Subsonic 3 tiene una Inflectorclase que me impresionó al convertirse PersonenPeople . Eché un vistazo a la fuente y descubrí que, naturalmente, hace un poco de trampa con una lista codificada, pero esa es realmente la única forma de hacerlo en inglés y cómo lo hacen los humanos: recordamos el singular y el plural de cada palabra y no solo aplicamos una regla . Como no hay masculino / femenino (/ neutral) para agregar a la mezcla, es mucho más simple.

Aquí hay un fragmento:

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

Explica algunas palabras que no tienen equivalentes en plural, como el ejemplo de equipo. Como probablemente pueda ver, hace un Regexreemplazo simple usando $ 1.

Actualización:
¡Parece que Subsonic Inflectores de hecho la clase Castle ActiveRecordInflector !

Chris S
fuente
2

No hay mucha documentación de MSDN sobre el uso específico de la clase PluralizationService, así que aquí hay una clase de prueba unitaria (NUnit) para mostrar el uso básico. Observe el extraño caso de prueba en la parte inferior que muestra que el servicio no es perfecto cuando se trata de formas plurales no estándar.

[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
fuente
1

Usando la base de datos de ejemplo Northwind de Microsoft:

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

Singularize no Singularize "Order_Details" Devuelve "Order_Details" con el sal final. ¿Cuál es la solución?

RandallTo
fuente
1
Esta es una pregunta, no una respuesta a una pregunta ... pero Pluralize () y Singularize () solo funcionan con palabras del diccionario. Hay una forma de agregar palabras usando ICustomPluralizationMapping.AddWord, pero al menos para mí esa no fue una muy buena solución cuando puede tener muchas palabras no reales como nombres en código.
tordal
@tordal Gracias, esto es exactamente por lo que vine a esta pregunta
Chad