Existe-t-il un algorithme en c # pour singulariser - pluraliser un mot?

106

Existe-t-il un algorithme en c # pour singulariser - pluraliser un mot (en anglais) ou existe-t-il une bibliothèque .net pour ce faire (peut-être également dans différentes langues)?

Ronnie
la source

Réponses:

182

Vous disposez également de System.Data.Entity.Design.PluralizationServices.PluralizationService .

MISE À JOUR : l'ancienne réponse mérite d'être mise à jour. Il y a maintenant aussi Humanizer: https://github.com/MehdiK/Humanizer

Daniel
la source
2
Hmmm êtes-vous autorisé à redistribuer, ou simplement à utiliser, une DLL de conception? Je demande cela parce que je sais que la licence de DevExpress interdit la redistribution de toute DLL .design.
Pierre-Alain Vigeant
58
L'ouverture du code avec ILSpy montre une classe appelée EnglishPluralizationService, qui a beaucoup de cas exceptionnels définis dans et rend la lecture intéressante. J'aime particulièrement `` pneumonoultramicroscopicsilicovolcanoconiosis '', que je me retrouve à utiliser tout le temps dans mes modèles d'entité ... 8o)
MrKWatkins
7
Je peux deviner comment cela a été ajouté. Un testeur a déposé un bug sur le développeur disant qu'il ne fonctionne pas pour ledit mot. Dev l'a corrigé. Les deux ont partagé un rire.
merlinbeard
2
@MrKWatkins Sonne plus comme 'supercalifragilisticexpialidocious'
Corstian Boerman
1
Humanizer est une excellente recommandation. J'avais bien sûr mis en œuvre 15% d'entre eux moi-même avant de découvrir qu'il existait.
Casey
18

Je peux le faire pour l'espéranto, sans cas particuliers!

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

Pour l'anglais, il serait utile de se familiariser avec les règles des pluriels réguliers de noms , ainsi que des pluriels irréguliers de noms . Il existe un article Wikipédia complet sur le pluriel anglais , qui peut également contenir des informations utiles.

Greg Hewgill
la source
5
Vous devriez le faire lancer si vous passez un verbe ou un adverbe!
Timwi
1
@Matt: Bien sûr, cela convient au cas nominatif; Je suis convaincu que l'extension de cette méthode au cas accusatif est simple pour un lecteur avisé.
Greg Hewgill
14

La plupart des ORM ont un coup de main, bien qu'ils ne soient généralement pas parfaits. Je sais que Castle a sa classe Inflector que vous pouvez probablement fouiller. Le faire "parfaitement" n'est cependant pas une tâche facile (les "règles" anglaises ne sont pas vraiment des règles :)), donc cela dépend si vous êtes satisfait d'une approche "raisonnable".

Steven Robbins
la source
D'après votre suggestion, j'ai cherché "Inflector" et j'ai trouvé ce andrewpeters.net/inflectornet qui devrait être fondamentalement le même que celui de Castle
Ronnie
4
En fait, ce n'est pas fondamentalement le même, c'est identique.
David Pfeffer
12

J'ai triché en Java - je voulais être capable de produire une chaîne correcte pour "Il y avait n quelque chose (s)", alors j'ai écrit le foll. méthode utilitaire peu surchargée:

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

invoqué comme ça

System.out.println("There were "+pluralize(count,"something"));
System.out.println("You have broken "+pluralize(count,"knife","knives"));
Lawrence Dol
la source
Cela ne couvre que de petites sections de grammaire, cela ne prend pas en compte les mots comme les quiz, les fêtes, les moitiés, les souris, les index, etc. C'est un bon premier coup, mais il y a beaucoup d'autres règles qui devraient probablement être traitées en premier .
Jeremy S
4
@Jeremy: Pourquoi pas?: Println ("Vous avez réussi" + singularPlural (nombre, "quiz", "quiz") + "jusqu'ici")
Lawrence Dol
J'interpréterai peut-être la question différemment. Je pense que l'algorithme devrait déterminer la forme plurielle sans aucune indication de la part du développeur, tandis que votre méthode impose au développeur de savoir quelle est la forme plurielle.
Jeremy S
3
@Jeremy: D'où le "J'ai triché ..." - ne semble pas justifier un vote défavorable.
Lawrence Dol
1
D'accord. Je pense également que les informations fournies étaient utiles, c'est pourquoi aucun vote négatif ne vient de moi. Je ne suis pas défavorable en général, dans le sens de la "jonque d'un homme ...".
Jeremy S
10

J'ai créé une petite bibliothèque pour cela en .net (C #), appelée Pluralizer (sans surprise).

Il est destiné à fonctionner avec des phrases complètes, quelque chose comme String.Format le fait.

Cela fonctionne essentiellement comme ceci:

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

Il peut également faire bien plus que cela. En savoir plus sur mon blog . Il est également disponible dans NuGet.

Jay Querido
la source
4
Ouais, cette bibliothèque ne fait que des mots uniques, et seulement des noms (bien que Pluralizer utilise cette classe en interne). Cette bibliothèque facilite la rédaction de phrases entières. Jetez un œil à mon blog pour plus d'exemples. Pluralizer.Instance.Pluralize ("{Elle} {va} à {sa | leur} {maison} respective.", 5)
Jay Querido
Shaun Wilson - Mon ordinateur est actuellement en pièces. Je me précipite pour le récupérer et je le mettrai à jour dans un jour ou deux. En attendant, nuget.org/packages?q=pluralizer
Jay Querido
8

J'en ai fouetté un ensemble basé sur le pluraliseur Rails. Vous pouvez voir mon article de blog ici , ou sur github ici

output = Formatting.Pluralization(100, "sausage"); 
Matt Grande
la source
3
Merci d'avoir partagé. Heureux de ne pas avoir besoin de faire référence à une autre assemblée.
hofnarwillie
1
Simple et beau !, mais il manque la fonctionnalité Singularize
amd
5

Comme la question était pour C #, voici une belle variante de la solution de Software Monkey (encore une fois un peu "triche", mais pour moi vraiment la façon la plus pratique et réutilisable de faire cela):

    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'utilisation est la suivante:

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

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

Subsonic 3 a une Inflectorclasse qui m'a impressionné en tournant Persondans People. J'ai jeté un coup d'œil à la source et j'ai trouvé que cela trompait naturellement un peu avec une liste codée en dur, mais c'est vraiment la seule façon de le faire en anglais et comment les humains le font - nous nous souvenons du singulier et du pluriel de chaque mot et n'appliquons pas seulement une règle . Comme il n'y a pas de masculin / féminin (/ neutre) à ajouter au mélange, c'est beaucoup plus simple.

Voici un extrait:

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

Il rend compte de certains mots n'ayant pas d'équivalents pluriels, comme l'exemple d'équipement. Comme vous pouvez probablement le constater, il effectue un Regexremplacement simple en utilisant $ 1.

Mise à jour:
Il semble que Subsonic Inflectorest en fait la classe Castle ActiveRecordInflector !

Chris S
la source
2

Pas beaucoup de documentation de MSDN sur l'utilisation spécifique de la classe PluralizationService donc voici une classe de test unitaire (NUnit) pour montrer l'utilisation de base. Remarquez le cas de test étrange en bas qui montre que le service n'est pas parfait lorsqu'il s'agit de formes plurielles 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
    }
}
Ryan Rodemoyer
la source
1

À l'aide de l'exemple de base de données Northwind de Microsoft:

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

Singularize ne singularise pas "Order_Details" Il renvoie "Order_Details" avec le sà la fin. Quel est le travail autour?

RandallTo
la source
1
Ceci est une question, pas une réponse à une question ... mais Pluralize () et Singularize () ne fonctionnent qu'avec les mots du dictionnaire. Il existe un moyen d'ajouter des mots en utilisant ICustomPluralizationMapping.AddWord, mais au moins pour moi, ce n'était pas une très bonne solution lorsque vous pouvez avoir beaucoup de mots non réels comme des noms de code.
tordal
@tordal Merci, c'est exactement ce pour quoi je suis venu à cette question
Tchad