Có thuật toán nào trong c # để phân biệt - đa nguyên một từ không?


106

Có thuật toán nào trong c # để phân biệt - đa phân hóa một từ (bằng tiếng Anh) hoặc có tồn tại một thư viện .net để thực hiện việc này (cũng có thể ở các ngôn ngữ khác nhau) không?

Câu trả lời:


182

Bạn cũng có System.Data.Entity.Design.PluificationServices.PluificationService .

CẬP NHẬT : Câu trả lời cũ đáng được cập nhật. Hiện có cả Nhân văn: https://github.com/MehdiK/Humanizer


2
Hmmm, bạn có được phép phân phối lại hay chỉ sử dụng, một DLL thiết kế? Tôi hỏi điều đó vì tôi biết rằng giấy phép cho DevExpress cấm phân phối lại bất kỳ tệp DLL .design nào.
Pierre-Alain Vigeant vào

58
Mở mã bằng ILSpy sẽ hiển thị một lớp có tên là EnglishPluificationService, lớp này có rất nhiều trường hợp đặc biệt được xác định và giúp cho việc đọc thú vị. Tôi đặc biệt thích 'Pneumonoultramicroscopicsilicovolcanoconiosis', mà tôi thấy mình sử dụng tất cả thời gian trong các mô hình thực thể của tôi ... 8o)
MrKWatkins

7
Tôi có thể đoán làm thế nào mà nó được thêm vào. Một người thử nghiệm đã gửi một lỗi cho nhà phát triển nói rằng nó không hoạt động với từ đã nói. Dev đã sửa nó. Cả hai cùng cười.
merlinbeard

2
@MrKWatkins Nghe giống như 'supercalifragilisticexpialidocious'
Corstian Boerman

1
Nhân văn là một khuyến nghị tuyệt vời. Tất nhiên, tôi đã tự mình thực hiện 15% trước khi phát hiện ra nó tồn tại.
Casey

18

Tôi có thể làm điều đó cho Esperanto, không có trường hợp đặc biệt!

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

Đối với tiếng Anh, sẽ rất hữu ích nếu làm quen với các quy tắc đối với Danh từ Số nhiều Thông thường , cũng như Số lượng Nhiều Danh từ Bất thường . Có cả một bài viết trên Wikipedia về số nhiều tiếng Anh , có thể có một số thông tin hữu ích.


5
Bạn nên làm cho nó ném nếu bạn chuyển vào một động từ hoặc trạng từ!
Timwi

1
@Matt: Tất nhiên điều này phù hợp với trường hợp được đề cử; Tôi tin tưởng rằng việc mở rộng phương pháp này cho trường hợp buộc tội là đơn giản đối với một độc giả sắc sảo.
Greg Hewgill,

14

Hầu hết các ORM đều gặp khó khăn, mặc dù chúng thường không hoàn hảo. Tôi biết Castle có Lớp Inflector mà bạn có thể có thể tham gia. Tuy nhiên, thực hiện nó một cách "hoàn hảo" không phải là một nhiệm vụ dễ dàng ("quy tắc" trong tiếng Anh không thực sự là quy tắc :)), vì vậy nó phụ thuộc vào việc bạn có hài lòng với cách tiếp cận "đoán hợp lý" hay không.


Từ gợi ý của bạn tôi đã tìm kiếm cho "Inflector" và thấy điều này andrewpeters.net/inflectornet rằng Linh hồn về cơ bản là giống nhau của một lâu đài
Ronnie

4
Trên thực tế về cơ bản nó không giống nhau, giống hệt nhau.
David Pfeffer

12

Tôi đã gian lận trong Java - tôi muốn có thể tạo ra một chuỗi chính xác cho "Có n cái gì đó", vì vậy tôi đã viết foll. phương thức tiện ích quá tải ít:

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

kêu gọi như vậy

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

Tuy nhiên, điều này chỉ bao gồm một phần nhỏ của ngữ pháp, nó không tính đến các từ như câu đố, bữa tiệc, một nửa, con chuột, chỉ số, v.v. Đây là một bước khởi đầu tốt, nhưng có rất nhiều quy tắc khác có thể nên được xử lý trước. .
Jeremy S

4
@ Jeremy: Tại sao không ?: println ( "Bạn đã trôi qua" + singularPlural (đếm, "đố", "câu đố") + "cho đến nay")
Lawrence Dol

Tôi có thể giải thích câu hỏi theo cách khác. Tôi nghĩ rằng thuật toán nên xác định dạng số nhiều mà không có bất kỳ gợi ý nào từ nhà phát triển, trong khi phương pháp của bạn giúp nhà phát triển biết được dạng số nhiều là gì.
Jeremy S

3
@Jeremy: Do đó, "Tôi đã lừa dối ..." dẫn đến - dường như không đảm bảo một phản đối.
Lawrence Dol

1
Đã đồng ý. Tôi cũng nghĩ rằng thông tin được cung cấp là hữu ích, đó là lý do tại sao bất kỳ phản đối nào không đến từ tôi. Nói chung, tôi không phản đối, dọc theo dòng "rác của một người ...".
Jeremy S

10

Tôi đã tạo một thư viện nhỏ cho điều này trong .net (C #), được gọi là Pluralizer (không ngạc nhiên).

Nó có nghĩa là làm việc với các câu đầy đủ, giống như String.Format.

Về cơ bản nó hoạt động như thế này:

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

Nó cũng có thể làm nhiều hơn thế. Đọc thêm về nó trên blog của tôi . Nó cũng có sẵn trong NuGet.



4
Đúng vậy, thư viện đó chỉ chứa các từ đơn và chỉ danh từ (mặc dù Pluralizer sử dụng lớp đó trong nội bộ). Thư viện này giúp viết toàn bộ câu dễ dàng hơn. Hãy xem blog của tôi để biết thêm ví dụ. Pluralizer.Instance.Pluralizer ("{She} {is} sẽ đến {her | their tương ứng} {home}.", 5)
Jay Querido

Shaun Wilson - Máy tính của tôi hiện đang ở các bộ phận. Tôi đang gấp rút sao lưu và sẽ cập nhật trong vòng một hoặc hai ngày. Trong thời gian này, nuget.org/packages?q=pluralizer
Jay Querido

8

Tôi đã đánh một cái với nhau dựa trên trình đa nguyên Rails. Bạn có thể xem bài đăng trên blog của tôi tại đây hoặc trên github tại đây

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

3
Cám ơn vì đã chia sẻ. Rất vui vì tôi không cần phải tham khảo một hội đồng khác.
hofnarwillie 29/09

1
Đơn giản và đẹp !, nhưng nó bỏ lỡ Singularize chức năng
amd

5

Như câu hỏi dành cho C #, đây là một biến thể hay về giải pháp của Software Monkey (một lần nữa là một chút "gian lận", nhưng đối với tôi thực sự là cách thực tế nhất và có thể tái sử dụng):

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

Cách sử dụng như sau:

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

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

3

Subsonic 3 có một Inflectorlớp học mà tôi ấn tượng bằng cách rẽ Personvào People. Tôi đã xem qua nguồn và thấy nó tự nhiên gian lận một chút với danh sách được mã hóa cứng nhưng đó thực sự là cách duy nhất để làm điều đó trong tiếng Anh và cách con người làm điều đó - chúng tôi nhớ số ít và số nhiều của mỗi từ và không chỉ áp dụng một quy tắc . Vì không có nam tính / nữ tính (/ trung tính) để thêm vào hỗn hợp, nó đơn giản hơn rất nhiều.

Đây là một đoạn mã:

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

Nó giải thích cho một số từ không có số nhiều tương đương, như ví dụ về thiết bị. Như bạn có thể biết, nó thực hiện một Regexthay thế đơn giản bằng cách sử dụng $ 1.

Cập nhật:
Có vẻ như Subsonic's không Inflectorgiống với lớp Castle ActiveRecordInflector !


2

Không có nhiều tài liệu từ MSDN về cách sử dụng cụ thể của lớp PlurationService, vì vậy đây là một lớp kiểm tra đơn vị (NUnit) để hiển thị cách sử dụng cơ bản. Lưu ý trường hợp kiểm tra kỳ lạ ở dưới cùng cho thấy dịch vụ không hoàn hảo khi nói đến các dạng số nhiều không chuẩn.

[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

Sử dụng cơ sở dữ liệu ví dụ về Northwind của Microsoft:

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

Singularize không Singularize "Order_Details" Nó trả về "Order_Details" với sphần cuối. Công việc xung quanh là gì?


1
Đây là một câu hỏi, không phải là một câu trả lời cho một câu hỏi ... nhưng Plurating () và Singularize () chỉ hoạt động với các từ điển. Có một cách để thêm các từ bằng cách sử dụng ICustomPlunatingMapping.AddWord, nhưng ít nhất đối với tôi, đó không phải là một giải pháp tốt khi bạn có thể có nhiều từ không có thật như tên mã.
tordal

@tordal Cảm ơn bạn, đây chính xác là những gì tôi đến với câu hỏi này
Chad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.