C # 'da tekilleştirmek - bir kelimeyi çoğullaştırmak için herhangi bir algoritma var mı?


106

C # 'da tekilleştirmek için herhangi bir algoritma var mı - bir kelimeyi çoğullaştırmak (İngilizce) veya bunu yapmak için bir .net kitaplığı var mı (farklı dillerde de olabilir)?

Yanıtlar:


182

Ayrıca System.Data.Entity.Design.PluralizationServices.PluralizationService'e de sahipsiniz .

GÜNCELLEME : Eski cevap güncellemeyi hak ediyor. Artık Humanizer da var: https://github.com/MehdiK/Humanizer


2
Hmmm, bir Tasarım DLL'sinin yeniden dağıtılmasına veya yalnızca kullanılmasına izin veriyor musunuz? Bunu soruyorum çünkü DevExpress lisansının herhangi bir .design DLL dosyasını yeniden dağıtmayı yasakladığını biliyorum.
Pierre-Alain Vigeant

58
Kodu ILSpy ile açmak, EnglishPluralizationService adlı, içinde tanımlanmış birçok istisnai durum içeren ve ilginç okuma sağlayan bir sınıfı gösterir. Varlık modellerimde her zaman kullandığım 'pneumonoultramicroscopicsilikovolcanoconiosis'i özellikle seviyorum ... 8o)
MrKWatkins

7
Nasıl eklendiğini tahmin edebiliyorum. Bir testçi, söz konusu kelime için işe yaramadığını söyleyerek geliştiriciye bir hata gönderdi. Dev düzeltti. İkisi de güldü.
merlinbeard

2
@MrKWatkins Sesler fazla gibi 'supercalifragilisticexpialidocious'
Corstian BOERMAN

1
İnsanlaştırıcı harika bir öneridir. Elbette var olduğunu öğrenmeden önce% 15'i kendim uyguladım.
Casey

18

Bunu Esperanto için özel durumlar olmadan yapabilirim!

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

İngilizce için, kuralları aşina olmak için yararlı olacağını Düzenli İsimlerin çoğul halleri yanı sıra İsimlerin düzensiz çoğul . İngilizce çoğul hakkında bazı yararlı bilgiler de içeren tam bir Wikipedia makalesi var.


5
Bir fiil ya da zarf geçirirsen onu fırlatmalısın!
Timwi

1
@Matt: Tabii ki bu aday durum için uygun; Bu yöntemi suçlayıcı vakaya genişletmenin zeki bir okuyucu için basit olduğuna inanıyorum.
Greg Hewgill

14

Genelde mükemmel olmasalar da, çoğu ORM'nin bıçağı vardır. Castle'ın Inflector Sınıfı olduğunu biliyorum, muhtemelen etrafı karıştırabilirsin. Bunu "mükemmel" yapmak kolay bir iş değildir (İngilizce "kurallar" aslında kural değildir :)), bu nedenle "makul tahmin" yaklaşımından memnun olup olmadığınıza bağlıdır.


Önerinizden " Inflector " ı aradım ve bu andrewpeters.net/inflectornet'i buldum, bu temelde Castle 1 ile aynı olabilir
Ronnie

4
Aslında temelde aynı değil, özdeş.
David Pfeffer

12

Java'da hile yaptım - "N tane bir şey vardı" için doğru bir dizgi üretebilmek istedim, bu yüzden dosyayı yazdım. biraz aşırı yüklenmiş yardımcı program yöntemi:

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

böyle çağrıldı

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

Bu sadece küçük bir dilbilgisi bölümlerini kapsar, sınavlar, partiler, yarımlar, fareler, indeksler vb. Kelimeleri hesaba katmaz. Bu iyi bir ilk bıçaktır, ancak muhtemelen önce işlenmesi gereken birçok başka kural vardır. .
Jeremy S

4
@Jeremy: Neden olmasın ?: println ("Geçtiniz" + singularPlural (sayı, "sınav", "sınavlar") + "şimdiye kadar")
Lawrence Dol

Soruyu farklı yorumluyor olabilirim. Metodunuz geliştiriciye çoğul formun ne olduğunu bilme sorumluluğunu yüklerken, algoritmanın geliştiriciden herhangi bir ipucu olmaksızın çoğul formu belirlemesi gerektiğini düşünüyorum.
Jeremy S

3
@Jeremy: Dolayısıyla "Hile yaptım ..." önderlik ediyor - olumsuz bir oy vermeyi gerektirmiyor.
Lawrence Dol

1
Kabul. Ayrıca sağlanan bilgilerin faydalı olduğunu düşünüyorum, bu yüzden benden olumsuz oy gelmedi. Genel olarak "bir adamın çöpü ..." şeklinde olumsuz oy kullanmam.
Jeremy S

10

Bunun için .net'te (C #) Pluralizer adında küçük bir kitaplık oluşturdum (şaşırtıcı olmayan bir şekilde).

String.Format'ın yaptığı gibi tam cümlelerle çalışması amaçlanmıştır.

Temelde şu şekilde çalışır:

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

Ayrıca bundan daha fazlasını da yapabilir. Blogumda bununla ilgili daha fazla bilgi edinin . NuGet'te de mevcuttur.



4
Evet, bu kitaplık yalnızca tek sözcükler ve yalnızca isimler yapar (Pluralizer bu sınıfı dahili olarak kullansa da). Bu kütüphane, tüm cümlelerin yazılmasını kolaylaştırır. Daha fazla örnek için bloguma bir göz atın. Pluralizer.Instance.Pluralize ("{She} {is} {ona | kendi} {eve} gidiyor.", 5)
Jay Querido

Shaun Wilson - Bilgisayarım şu anda parçalar halinde. Onu geri almak için acele ediyorum ve bir veya iki gün içinde güncellenecek. Bu arada nuget.org/packages?q=pluralizer
Jay Querido

8

Rails çoğullaştırıcısına göre bir tanesini birlikte çırptım. Blog gönderimi burada veya github'da burada görebilirsiniz

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

3
Paylaşım için teşekkürler. Başka bir meclise başvurmam gerekmediğine sevindim.
hofnarwillie

1
Basit ve güzel !, ancak Singularize işlevini kaçırıyor
amd

5

Soru C # için olduğu gibi, burada Software Monkey'nin çözümünün güzel bir varyasyonu var (yine biraz "hile", ama benim için bunu yapmanın gerçekten en pratik ve yeniden kullanılabilir yolu):

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

Kullanım aşağıdaki gibidir:

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

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

3

Sesaltı 3 bir sahiptir Inflectorçevirerek beni etkiledi sınıfını Personiçine People. Kaynağa baktım ve doğal olarak kodlanmış bir liste ile biraz hile yaptığını buldum ama bu gerçekten bunu İngilizce yapmanın tek yolu ve insanlar bunu nasıl yapıyor - her kelimenin tekil ve çoğulunu hatırlıyoruz ve sadece bir kural uygulamıyoruz . Karışıma eklenecek erkeksi / dişil (/ nötr) olmadığı için çok daha basit.

İşte bir pasaj:

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

Ekipman örneği gibi, çoğul eşdeğerleri olmayan bazı kelimeleri açıklar. Muhtemelen söyleyebileceğiniz gibi, Regex$ 1 kullanarak basit bir değişiklik yapar .

Güncelleme:
Görünüşe göre Subsonic Inflector, Castle ActiveRecordInflector sınıfına ait!


2

PluralizationService sınıfının özel kullanımıyla ilgili MSDN'den çok fazla belge yok, bu nedenle burada temel kullanımı göstermek için bir birim test sınıfı (NUnit) var. Standart olmayan çoğul biçimler söz konusu olduğunda hizmetin mükemmel olmadığını gösteren alttaki tuhaf test durumuna dikkat edin.

[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

Microsoft'un Northwind örnek veritabanını kullanarak:

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

Singularize, "Order_Details" i Tekilleştirmez Sonunda "Order_Details" i döndürür s. İşin etrafında ne var?


1
Bu bir sorudur, bir sorunun cevabı değil ... ama Pluralize () ve Singularize () sadece sözlük kelimeleriyle çalışır. ICustomPluralizationMapping.AddWord kullanarak kelime eklemenin bir yolu var, ancak en azından benim için kod adları gibi gerçek olmayan birçok kelimeye sahip olduğunuzda bu pek iyi bir çözüm değildi.
tordal

@tordal Teşekkürler, tam olarak bu soruya geldim
Çad,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.