開源項目Humanizer介紹


  Humanizer 能夠滿足您所有.Net關於操作和展示以下類型的需求,包括字符串、枚舉、日期、時間、時間跨度、數字和數量。它采用 MIT 進行授權分發。

 

1、人性化字符串

人性化的字符串擴展名使您可以將原本由計算機處理的字符串轉換為更具可讀性的人性化字符串。 它的基礎是在BDDfy框架中設置的,在該框架中,類名,方法名和屬性被轉換為易於閱讀的句子。

"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence"

"Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence"

"Underscored_input_String_is_turned_INTO_sentence".Humanize() => "Underscored input String is turned INTO sentence"

請注意,僅包含大寫字母且僅包含一個單詞的字符串始終被視為首字母縮寫詞(無論其長度如何)。 為了確保任何字符串都將始終被人性化,您必須使用轉換(請參見下面的Transform方法):

// acronyms are left intact
"HTML".Humanize() => "HTML"

// any unbroken upper case string is treated as an acronym
"HUMANIZER".Humanize() => "HUMANIZER"
"HUMANIZER".Transform(To.LowerCase, To.TitleCase) => "Humanizer"

您還可以指定所需的字母大小寫:

"CanReturnTitleCase".Humanize(LetterCasing.Title) => "Can Return Title Case"

"Can_return_title_Case".Humanize(LetterCasing.Title) => "Can Return Title Case"

"CanReturnLowerCase".Humanize(LetterCasing.LowerCase) => "can return lower case"

"CanHumanizeIntoUpperCase".Humanize(LetterCasing.AllCaps) => "CAN HUMANIZE INTO UPPER CASE"

LetterCasing API和接受它的方法是V0.2時代的遺留物,將來會不推薦使用。 代替的是,您可以使用下面介紹的Transform方法。

 

2、非人性化的字符串

就像您可以將計算機友好的字符串人性化為人類友好的字符串一樣,您也可以將人類友好的字符串人性化為計算機友好的字符串:

"Pascal case input string is turned into sentence".Dehumanize() => "PascalCaseInputStringIsTurnedIntoSentence"

 

3、轉換字符串

有一種Transform方法可以代替接受LetterCasing的LetterCasing,ApplyCase和Humanize重載。 轉換方法簽名如下:

string Transform(this string input, params IStringTransformer[] transformers)

對於字母大小寫,還有一些IStringTransformer的現成實現:

"Sentence casing".Transform(To.LowerCase) => "sentence casing"
"Sentence casing".Transform(To.SentenceCase) => "Sentence casing"
"Sentence casing".Transform(To.TitleCase) => "Sentence Casing"
"Sentence casing".Transform(To.UpperCase) => "SENTENCE CASING"

LowerCase是To類的公共靜態屬性,它返回私有ToLowerCase類的實例,該實例實現IStringTransformer並知道如何將字符串轉換為小寫。

與ApplyCase和LetterCasing相比,使用Transform和IStringTransformer的好處是LetterCasing是枚舉,並且您只能使用框架中的內容,而IStringTransformer是可以在代碼庫中一次實現並與Transform方法一起使用的接口,從而可以輕松擴展 。

 

4、截斷字符串

您可以使用Truncate方法截斷字符串:

"Long text to truncate".Truncate(10) => "Long text…"

默認情況下,“ ...”字符用於截斷字符串。 使用'...'字符而不是“ ...”的優點是前者僅使用一個字符,因此允許在截斷之前顯示更多文本。 如果需要,還可以提供自己的截斷字符串:

"Long text to truncate".Truncate(10, "---") => "Long te---"

默認的截斷策略Truncator.FixedLength是將輸入字符串截斷為特定長度,包括截斷字符串的長度。 還有兩種其他的截斷器策略:一種用於固定數量的(字母數字)字符,另一種用於固定數量的單詞。 要在截斷時使用特定的截斷器,前面示例中顯示的兩個Truncate方法都具有重載,允許您指定用於截斷的ITruncator實例。 以下是有關如何使用提供的三個截斷符的示例:

"Long text to truncate".Truncate(10, Truncator.FixedLength) => "Long text…"
"Long text to truncate".Truncate(10, "---", Truncator.FixedLength) => "Long te---"

"Long text to truncate".Truncate(6, Truncator.FixedNumberOfCharacters) => "Long t…"
"Long text to truncate".Truncate(6, "---", Truncator.FixedNumberOfCharacters) => "Lon---"

"Long text to truncate".Truncate(2, Truncator.FixedNumberOfWords) => "Long text…"
"Long text to truncate".Truncate(2, "---", Truncator.FixedNumberOfWords) => "Long text---"

請注意,您還可以通過實現ITruncator接口來使用創建自己的截斷器。

還有一個選項可以選擇是從開頭(TruncateFrom.Left)還是結尾(TruncateFrom.Right)截斷字符串。 如上面的示例所示,默認設置為右側。 下面的示例顯示如何從字符串的開頭截斷:

"Long text to truncate".Truncate(10, Truncator.FixedLength, TruncateFrom.Left) => "… truncate"
"Long text to truncate".Truncate(10, "---", Truncator.FixedLength, TruncateFrom.Left) => "---runcate"

"Long text to truncate".Truncate(10, Truncator.FixedNumberOfCharacters, TruncateFrom.Left) => "…o truncate"
"Long text to truncate".Truncate(16, "---", Truncator.FixedNumberOfCharacters, TruncateFrom.Left) => "---ext to truncate"

"Long text to truncate".Truncate(2, Truncator.FixedNumberOfWords, TruncateFrom.Left) => "…to truncate"
"Long text to truncate".Truncate(2, "---", Truncator.FixedNumberOfWords, TruncateFrom.Left) => "---to truncate"

 

5、格式化字符串

您可以使用FormatWith()方法設置字符串格式:

"To be formatted -> {0}/{1}.".FormatWith(1, "A") => "To be formatted -> 1/A."

這是基於String.Format的擴展方法,因此確切的規則適用於它。 如果format為null,則將引發ArgumentNullException。 如果傳遞的參數數目較少,則會引發String.FormatException異常。

您還可以指定區域性以顯式用作FormatWith()方法的第一個參數:

"{0:N2}".FormatWith(new CultureInfo("ru-RU"), 6666.66) => "6 666,66"

如果未指定區域性,則使用當前線程的當前區域性。

 

6、人性化枚舉

直接在枚舉成員上調用ToString通常會給用戶帶來不理想的輸出。 解決方案通常是使用DescriptionAttribute數據注釋,然后在運行時讀取該注釋以獲得更友好的輸出。 那是一個很好的解決方案。 但是通常,我們只需要在枚舉成員的單詞之間放置一些空格-這就是String.Humanize()的優點。 對於像這樣的枚舉:

public enum EnumUnderTest
{
    [Description("Custom description")]
    MemberWithDescriptionAttribute,
    MemberWithoutDescriptionAttribute,
    ALLCAPITALS
}

你會得到:

// DescriptionAttribute is honored
EnumUnderTest.MemberWithDescriptionAttribute.Humanize() => "Custom description"

// In the absence of Description attribute string.Humanizer kicks in
EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize() => "Member without description attribute"

// Of course you can still apply letter casing
EnumUnderTest.MemberWithoutDescriptionAttribute.Humanize().Transform(To.TitleCase) => "Member Without Description Attribute"

您不僅限於DescriptionAttribute作為自定義描述。 應用於具有字符串Description屬性的枚舉成員的任何屬性都將計數。 這是為了幫助缺少DescriptionAttribute的平台,也允許使用DescriptionAttribute的子類。

您甚至可以配置attibute屬性的名稱以用作描述。

Configurator.EnumDescriptionPropertyLocator = p => p.Name == "Info"

如果需要提供本地化的描述,則可以改用DisplayAttribute數據注釋。

public enum EnumUnderTest
{
    [Display(Description = "EnumUnderTest_Member", ResourceType = typeof(Project.Resources))]
    Member
}

你會得到:

EnumUnderTest.Member.Humanize() => "content" // from Project.Resources found under "EnumUnderTest_Member" resource key

希望這將有助於避免亂定義帶有不必要屬性的枚舉!

 

7、使枚舉非人性化

將字符串人性化,使其原本是人性化的枚舉! 該API如下所示:

public static TTargetEnum DehumanizeTo<TTargetEnum>(this string input)

用法是:

"Member without description attribute".DehumanizeTo<EnumUnderTest>() => EnumUnderTest.MemberWithoutDescriptionAttribute

就像Humanize API一樣,它使用Description屬性。 您無需提供在人性化過程中提供的外殼:它可以弄清楚。

當在編譯時不知道原始Enum時,還有一個非泛型對應項:

public static Enum DehumanizeTo(this string input, Type targetEnum, NoMatch onNoMatch = NoMatch.ThrowsException)

可以像這樣使用:

"Member without description attribute".DehumanizeTo(typeof(EnumUnderTest)) => EnumUnderTest.MemberWithoutDescriptionAttribute

默認情況下,兩個方法都無法將提供的輸入與目標枚舉進行匹配時拋出NoMatchFoundException。 在非泛型方法中,您還可以通過將第二個可選參數設置為NoMatch.ReturnsNull來要求該方法返回null。

 

8、人性化DateTime

您可以對DateTime或DateTimeOffset的實例進行人性化,並返回一個字符串,該字符串告訴您時間上的倒退或前進時間:

DateTime.UtcNow.AddHours(-30).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(-2).Humanize() => "2 hours ago"

DateTime.UtcNow.AddHours(30).Humanize() => "tomorrow"
DateTime.UtcNow.AddHours(2).Humanize() => "2 hours from now"

DateTimeOffset.UtcNow.AddHours(1).Humanize() => "an hour from now"

Humanizer支持本地和UTC日期以及具有偏移量的日期(DateTimeOffset)。 您還可以提供要與輸入日期進行比較的日期。 如果為null,它將使用當前日期作為比較基礎。 另外,可以明確指定要使用的文化。 如果不是,則使用當前線程的當前UI文化。 這是API簽名:

public static string Humanize(this DateTime input, bool utcDate = true, DateTime? dateToCompareAgainst = null, CultureInfo culture = null)
public static string Humanize(this DateTimeOffset input, DateTimeOffset? dateToCompareAgainst = null, CultureInfo culture = null)

此方法有許多本地化版本。 以下是一些示例:

// In ar culture
DateTime.UtcNow.AddDays(-1).Humanize() => "أمس"
DateTime.UtcNow.AddDays(-2).Humanize() => "منذ يومين"
DateTime.UtcNow.AddDays(-3).Humanize() => "منذ 3 أيام"
DateTime.UtcNow.AddDays(-11).Humanize() => "منذ 11 يوم"

// In ru-RU culture
DateTime.UtcNow.AddMinutes(-1).Humanize() => "минуту назад"
DateTime.UtcNow.AddMinutes(-2).Humanize() => "2 минуты назад"
DateTime.UtcNow.AddMinutes(-10).Humanize() => "10 минут назад"
DateTime.UtcNow.AddMinutes(-21).Humanize() => "21 минуту назад"
DateTime.UtcNow.AddMinutes(-22).Humanize() => "22 минуты назад"
DateTime.UtcNow.AddMinutes(-40).Humanize() => "40 минут назад"

DateTime.Humanize有兩種策略:如上所述的默認策略和基於精度的策略。 要使用基於精度的策略,您需要對其進行配置:

Configurator.DateTimeHumanizeStrategy = new PrecisionDateTimeHumanizeStrategy(precision: .75);
Configurator.DateTimeOffsetHumanizeStrategy = new PrecisionDateTimeOffsetHumanizeStrategy(precision: .75); // configure when humanizing DateTimeOffset

默認精度設置為.75,但是您也可以傳遞所需的精度。 將精度設置為0.75:

44 seconds => 44 seconds ago/from now
45 seconds => one minute ago/from now
104 seconds => one minute ago/from now
105 seconds => two minutes ago/from now

25 days => a month ago/from now

日期沒有非人性化,因為人性化是有損的轉換,並且人類友好的日期是不可逆的。

 

9、人性化的時間跨度

您可以在TimeSpan上調用Humanize以獲得人性化的表示形式:

TimeSpan.FromMilliseconds(1).Humanize() => "1 millisecond"
TimeSpan.FromMilliseconds(2).Humanize() => "2 milliseconds"
TimeSpan.FromDays(1).Humanize() => "1 day"
TimeSpan.FromDays(16).Humanize() => "2 weeks"

TimeSpan.Humanize有一個可選的precision參數,它允許您指定返回值的精度。 精度的默認值為1,這意味着僅返回最大的時間單位,如您在TimeSpan.FromDays(16).Humanize()中看到的那樣。 以下是一些指定精度的示例:

TimeSpan.FromDays(1).Humanize(precision:2) => "1 day" // no difference when there is only one unit in the provided TimeSpan
TimeSpan.FromDays(16).Humanize(2) => "2 weeks, 2 days"

// the same TimeSpan value with different precision returns different results
TimeSpan.FromMilliseconds(1299630020).Humanize() => "2 weeks"
TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"
TimeSpan.FromMilliseconds(1299630020).Humanize(4) => "2 weeks, 1 day, 1 hour, 30 seconds"
TimeSpan.FromMilliseconds(1299630020).Humanize(5) => "2 weeks, 1 day, 1 hour, 30 seconds, 20 milliseconds"

默認情況下,使用精度參數時,空時間單位不計入返回值的精度。 如果您不需要這種行為,則可以將重載的TimeSpan.Humanize方法與countEmptyUnits參數一起使用。 前導的空時間單位永遠不會計數。 這是顯示空單位計數的區別的示例:

TimeSpan.FromMilliseconds(3603001).Humanize(3) => "1 hour, 3 seconds, 1 millisecond"
TimeSpan.FromMilliseconds(3603001).Humanize(3, countEmptyUnits:true) => "1 hour, 3 seconds"

此方法有許多本地化版本:

// in de-DE culture
TimeSpan.FromDays(1).Humanize() => "Ein Tag"
TimeSpan.FromDays(2).Humanize() => "2 Tage"

// in sk-SK culture
TimeSpan.FromMilliseconds(1).Humanize() => "1 milisekunda"
TimeSpan.FromMilliseconds(2).Humanize() => "2 milisekundy"
TimeSpan.FromMilliseconds(5).Humanize() => "5 milisekúnd"

可以明確指定要使用的文化。 如果不是,則使用當前線程的當前UI文化。 例:

TimeSpan.FromDays(1).Humanize(culture: "ru-RU") => "один день"

另外,可以指定最短的時間單位,以避免滾動到較小的單位。 例如:

TimeSpan.FromMilliseconds(122500).Humanize(minUnit: TimeUnit.Second) => "2 minutes, 2 seconds"    // instead of 2 minutes, 2 seconds, 500 milliseconds
TimeSpan.FromHours(25).Humanize(minUnit: TimeUnit.Day) => "1 Day"   //instead of 1 Day, 1 Hour

另外,可以指定最大時間單位以避免累加到下一個最大單位。 例如:

TimeSpan.FromDays(7).Humanize(maxUnit: TimeUnit.Day) => "7 days"    // instead of 1 week
TimeSpan.FromMilliseconds(2000).Humanize(maxUnit: TimeUnit.Millisecond) => "2000 milliseconds"    // instead of 2 seconds

默認的maxUnit為TimeUnit.Week,因為它可以提供准確的結果。 您可以將此值增加到TimeUnit.Month或TimeUnit.Year,這將為您提供基於每年365.2425天和每月30.436875天的近似值。 因此,月份的間隔為30到31天,每四年為366天。

TimeSpan.FromDays(486).Humanize(maxUnit: TimeUnit.Year, precision: 7) => "1 year, 3 months, 29 days" // One day further is 1 year, 4 month
TimeSpan.FromDays(517).Humanize(maxUnit: TimeUnit.Year, precision: 7) => "1 year, 4 months, 30 days" // This month has 30 days and one day further is 1 year, 5 months

如果有多個時間單位,則使用“,”字符串將它們組合起來:

TimeSpan.FromMilliseconds(1299630020).Humanize(3) => "2 weeks, 1 day, 1 hour"

當TimeSpan為零時,默認行為將返回“ 0”加上最小時間單位。 但是,如果在調用Humanize時將true分配給toWords,則該方法將返回“ no time”。 例如:

TimeSpan.Zero.Humanize(1) => "0 milliseconds"
TimeSpan.Zero.Humanize(1, toWords: true) => "no time"
TimeSpan.Zero.Humanize(1, minUnit: Humanizer.Localisation.TimeUnit.Second) => "0 seconds"

使用collectionSeparator參數,可以指定自己的分隔符字符串:

TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: " - ") => "2 weeks - 1 day - 1 hour"

也可以使用當前區域性的集合格式化程序來組合時間單位。 為此,將null指定為collectionSeparator參數:

// in en-US culture
TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: null) => "2 weeks, 1 day, and 1 hour"

// in de-DE culture
TimeSpan.FromMilliseconds(1299630020).Humanize(3, collectionSeparator: null) => "2 Wochen, Ein Tag und Eine Stunde"

如果單詞優先於數字,則可以設置toWords:true參數,以將人性化的TimeSpan中的數字轉換為單詞:

TimeSpan.FromMilliseconds(1299630020).Humanize(3,toWords:true)=>“兩個星期,一天,一個小時”

 

10、人性化集合

您可以在任何IEnumerable上調用Humanize,以獲取格式正確的字符串,該字符串表示集合中的對象。 默認情況下,將在每個項目上調用ToString()以獲取其表示形式,但是可以將格式化函數傳遞給Humanize。 此外,提供了一個默認的分隔符(英語中為“ and”),但是可以將其他分隔符傳遞給Humanize。

例如:

class SomeClass
{
    public string SomeString;
    public int SomeInt;
    public override string ToString()
    {
        return "Specific String";
    }
}

string FormatSomeClass(SomeClass sc)
{
    return string.Format("SomeObject #{0} - {1}", sc.SomeInt, sc.SomeString);
}

var collection = new List<SomeClass>
{
    new SomeClass { SomeInt = 1, SomeString = "One" },
    new SomeClass { SomeInt = 2, SomeString = "Two" },
    new SomeClass { SomeInt = 3, SomeString = "Three" }
};

collection.Humanize()                                    // "Specific String, Specific String, and Specific String"
collection.Humanize("or")                                // "Specific String, Specific String, or Specific String"
collection.Humanize(FormatSomeClass)                     // "SomeObject #1 - One, SomeObject #2 - Two, and SomeObject #3 - Three"
collection.Humanize(sc => sc.SomeInt.Ordinalize(), "or") // "1st, 2nd, or 3rd"

修剪項目,並跳過空白(NullOrWhitespace)項目。 這導致干凈的逗號標點。 (如果有自定義格式器功能,則此功能僅適用於格式器的輸出。)

您可以通過實現ICollectionFormatter並向Configurator.CollectionFormatters注冊它來提供自己的集合格式化程序。

 

11、Inflector 方法

還有一些 inflector 方法:

 

復數

在考慮不規則和不可數詞的情況下,將提供的輸入復數化:

"Man".Pluralize() => "Men"
"string".Pluralize() => "strings"

通常,您將對單個單詞調用Pluralize,但如果不確定單詞的奇異性,則可以使用可選的inputIsKnownToBeSingular參數調用該方法:

"Men".Pluralize(inputIsKnownToBeSingular: false) => "Men"
"Man".Pluralize(inputIsKnownToBeSingular: false) => "Men"
"string".Pluralize(inputIsKnownToBeSingular: false) => "strings"

具有復數參數的Pluralize重載已過時,在2.0版中已刪除。

 

單數化

單數將提供的輸入單數化,同時考慮不規則和不可數的單詞:

"Men".Singularize() => "Man"
"strings".Singularize() => "string"

通常,您會在一個復數單詞上調用單數化,但是如果不確定該單詞的復數形式,則可以使用可選的inputIsKnownToBePlural參數調用該方法:

"Men".Singularize(inputIsKnownToBePlural: false) => "Man"
"Man".Singularize(inputIsKnownToBePlural: false) => "Man"
"strings".Singularize(inputIsKnownToBePlural: false) => "string"

具有復數參數的Singularize重載已過時,並且在2.0版中已刪除。

 

12、添加單詞

有時,您可能需要從單數/復數詞匯表中添加一條規則(以下示例已在Inflector使用的默認詞匯表中):

// Adds a word to the vocabulary which cannot easily be pluralized/singularized by RegEx.
// Will match both "salesperson" and "person".
Vocabularies.Default.AddIrregular("person", "people");

// To only match "person" and not "salesperson" you would pass false for the 'matchEnding' parameter.
Vocabularies.Default.AddIrregular("person", "people", matchEnding: false);

// Adds an uncountable word to the vocabulary.  Will be ignored when plurality is changed:
Vocabularies.Default.AddUncountable("fish");

// Adds a rule to the vocabulary that does not follow trivial rules for pluralization:
Vocabularies.Default.AddPlural("bus", "buses");

// Adds a rule to the vocabulary that does not follow trivial rules for singularization
// (will match both "vertices" -> "vertex" and "indices" -> "index"):
Vocabularies.Default.AddSingular("(vert|ind)ices$", "$1ex");

到數量

很多時候,您想調用單數化和復數化為單詞加上數字。 例如 “ 2個請求”,“ 3個男人”。 ToQuantity為提供的單詞加上數字前綴,並相應地對該單詞進行復數或單數化:

"case".ToQuantity(0) => "0 cases"
"case".ToQuantity(1) => "1 case"
"case".ToQuantity(5) => "5 cases"
"man".ToQuantity(0) => "0 men"
"man".ToQuantity(1) => "1 man"
"man".ToQuantity(2) => "2 men"

ToQuantity可以判斷輸入單詞是單數還是復數,並在必要時將單數或復數:

"men".ToQuantity(2) => "2 men"
"process".ToQuantity(2) => "2 processes"
"process".ToQuantity(1) => "1 process"
"processes".ToQuantity(2) => "2 processes"
"processes".ToQuantity(1) => "1 process"

您還可以將第二個參數ShowQuantityAs傳遞給ToQuantity,以指定希望如何輸出提供的數量。 默認值為ShowQuantityAs.Numeric,這是我們在上面看到的。 其他兩個值是ShowQuantityAs.Words和ShowQuantityAs.None。

"case".ToQuantity(5, ShowQuantityAs.Words) => "five cases"
"case".ToQuantity(5, ShowQuantityAs.None) => "cases"

還有一個重載,允許您格式化數字。 您可以傳遞要使用的格式和文化。

"dollar".ToQuantity(2, "C0", new CultureInfo("en-US")) => "$2 dollars"
"dollar".ToQuantity(2, "C2", new CultureInfo("en-US")) => "$2.00 dollars"
"cases".ToQuantity(12000, "N0") => "12,000 cases"

序數化

序數化將數字轉換為序數字符串,用於表示有序序列(例如1st,2nd,3rd,4th)中的位置:

1.Ordinalize() => "1st"
5.Ordinalize() => "5th"

您還可以在數字字符串上調用Ordinalize並獲得相同的結果:“ 21” .Ordinalize()=>“ 21st”

序數化還支持兩種形式的語法性別。 您可以將一個參數傳遞給Ordinalize,以指定數字應以哪種性別輸出。可能的值為GrammaticalGender.Masculine,GrammmicalGender.Feminine和GrammaticalGender.Neuter:

// for Brazilian Portuguese locale
1.Ordinalize(GrammaticalGender.Masculine) => ""
1.Ordinalize(GrammaticalGender.Feminine) => ""
1.Ordinalize(GrammaticalGender.Neuter) => ""
"2".Ordinalize(GrammaticalGender.Masculine) => ""
"2".Ordinalize(GrammaticalGender.Feminine) => ""
"2".Ordinalize(GrammaticalGender.Neuter) => ""

顯然,這僅適用於某些文化。 對於其他通過性別或根本不通過的人,結果沒有任何區別。

標題化

Titleize將輸入的單詞轉換為Title大小寫; 等效於“某些標題”。Humanize(LetterCasing.Title)

Pascalize

Pascalize將輸入的單詞轉換為UpperCamelCase,還刪除下划線和空格:

"some_title for something".Pascalize() => "SomeTitleForSomething"

Camelize

Camelize的行為與Pascalize相同,但第一個字符為小寫:

"some_title for something".Camelize() => "someTitleForSomething"

下划線

Underscore用下划線分隔輸入的單詞:

"SomeTitle".Underscore() => "some_title"

Dasherize & Hyphenate

Dasherize和Hyphenate用下划線替換下划線:

"some_title".Dasherize() => "some-title"
"some_title".Hyphenate() => "some-title"
Kebaberize
Kebaberize用連字符分隔輸入的單詞,所有單詞都轉換為小寫
"SomeText".Kebaberize() => "some-text"

 

13、流利的日期

Humanizer提供了一種流利的API來處理DateTime和TimeSpan,如下所示:

TimeSpan方法:

2.Milliseconds() => TimeSpan.FromMilliseconds(2)
2.Seconds() => TimeSpan.FromSeconds(2)
2.Minutes() => TimeSpan.FromMinutes(2)
2.Hours() => TimeSpan.FromHours(2)
2.Days() => TimeSpan.FromDays(2)
2.Weeks() => TimeSpan.FromDays(14)

每月或一年都沒有流利的API,因為一個月可能有28到31天,一年可能是365或366天。

您可以使用這些方法來替換

DateTime.Now.AddDays(2).AddHours(3).AddMinutes(-5)

DateTime.Now + 2.Days() + 3.Hours() - 5.Minutes()

還可以使用三類流利的方法來處理DateTime:

In.TheYear(2010) // Returns the first of January of 2010
In.January // Returns 1st of January of the current year
In.FebruaryOf(2009) // Returns 1st of February of 2009

In.One.Second //  DateTime.UtcNow.AddSeconds(1);
In.Two.SecondsFrom(DateTime dateTime)
In.Three.Minutes // With corresponding From method
In.Three.Hours // With corresponding From method
In.Three.Days // With corresponding From method
In.Three.Weeks // With corresponding From method
In.Three.Months // With corresponding From method
In.Three.Years // With corresponding From method

On.January.The4th // Returns 4th of January of the current year
On.February.The(12) // Returns 12th of Feb of the current year

和一些擴展方法:

var someDateTime = new DateTime(2011, 2, 10, 5, 25, 45, 125);

// Returns new DateTime(2008, 2, 10, 5, 25, 45, 125) changing the year to 2008
someDateTime.In(2008)

// Returns new DateTime(2011, 2, 10, 2, 25, 45, 125) changing the hour to 2:25:45.125
someDateTime.At(2)

// Returns new DateTime(2011, 2, 10, 2, 20, 15, 125) changing the time to 2:20:15.125
someDateTime.At(2, 20, 15)

// Returns new DateTime(2011, 2, 10, 12, 0, 0) changing the time to 12:00:00.000
someDateTime.AtNoon()

// Returns new DateTime(2011, 2, 10, 0, 0, 0) changing the time to 00:00:00.000
someDateTime.AtMidnight()

顯然,您也可以將這些方法鏈接在一起。 例如 2010年11月13日在中午+ 5分鍾()

 

14、數字到數字

Humanizer提供了一種流暢的API,該API以更清晰的方式生成(通常是很大的)數字:

1.25.Billions() => 1250000000
3.Hundreds().Thousands() => 300000

 

15、數字到單詞

Humanizer可以使用ToWords擴展名將數字更改為單詞:

1.ToWords() => "one"
10.ToWords() => "ten"
11.ToWords() => "eleven"
122.ToWords() => "one hundred and twenty-two"
3501.ToWords() => "three thousand five hundred and one"

您還可以將第二個參數GrammaticalGender傳遞給ToWords,以指定應該輸出數字的性別。可能的值為GrammaticalGender.Masculine,GrammaticalGender.Feminine和GrammaticalGender.Neuter:

// for Russian locale
1.ToWords(GrammaticalGender.Masculine) => "один"
1.ToWords(GrammaticalGender.Feminine) => "одна"
1.ToWords(GrammaticalGender.Neuter) => "одно"
// for Arabic locale
1.ToWords(GrammaticalGender.Masculine) => "واحد"
1.ToWords(GrammaticalGender.Feminine) => "واحدة"
1.ToWords(GrammaticalGender.Neuter) => "واحد"
(-1).ToWords() => "ناقص واحد"

顯然,這僅適用於某些文化。 對於傳遞性別的其他人來說,結果沒有任何區別。

另外,可以明確指定要使用的文化。 如果不是,則使用當前線程的當前UI文化。 這是一個例子:

11.ToWords(new CultureInfo("en")) => "eleven"
1.ToWords(GrammaticalGender.Masculine, new CultureInfo("ru")) => "один"

 

16、數字到序數詞

這是將ToWords與Ordinalize混合在一起的一種。 您可以在數字上調用ToOrdinalWords以獲得數字中單詞的序號表示! 例如:

0.ToOrdinalWords() => "zeroth"
1.ToOrdinalWords() => "first"
2.ToOrdinalWords() => "second"
8.ToOrdinalWords() => "eighth"
10.ToOrdinalWords() => "tenth"
11.ToOrdinalWords() => "eleventh"
12.ToOrdinalWords() => "twelfth"
20.ToOrdinalWords() => "twentieth"
21.ToOrdinalWords() => "twenty first"
121.ToOrdinalWords() => "hundred and twenty first"

ToOrdinalWords也支持語法性別。 您可以將第二個參數傳遞給ToOrdinalWords以指定輸出的性別。 可能的值為GrammaticalGender.Masculine,GrammmicalGender.Feminine和GrammaticalGender.Neuter:

// for Brazilian Portuguese locale
1.ToOrdinalWords(GrammaticalGender.Masculine) => "primeiro"
1.ToOrdinalWords(GrammaticalGender.Feminine) => "primeira"
1.ToOrdinalWords(GrammaticalGender.Neuter) => "primeiro"
2.ToOrdinalWords(GrammaticalGender.Masculine) => "segundo"
2.ToOrdinalWords(GrammaticalGender.Feminine) => "segunda"
2.ToOrdinalWords(GrammaticalGender.Neuter) => "segundo"
// for Arabic locale
1.ToOrdinalWords(GrammaticalGender.Masculine) => "الأول"
1.ToOrdinalWords(GrammaticalGender.Feminine) => "الأولى"
1.ToOrdinalWords(GrammaticalGender.Neuter) => "الأول"
2.ToOrdinalWords(GrammaticalGender.Masculine) => "الثاني"
2.ToOrdinalWords(GrammaticalGender.Feminine) => "الثانية"
2.ToOrdinalWords(GrammaticalGender.Neuter) => "الثاني"

顯然,這僅適用於某些文化。 對於傳遞性別的其他人來說,結果沒有任何區別。

另外,可以明確指定要使用的文化。 如果不是,則使用當前線程的當前UI文化。 這是一個例子:

10.ToOrdinalWords(new CultureInfo("en-US")) => "tenth"
1.ToOrdinalWords(GrammaticalGender.Masculine, new CulureInfo("pt-BR")) => "primeiro"

 

17、日期時間到序數詞

這是Ordinalize的擴展

// for English UK locale
new DateTime(2015, 1, 1).ToOrdinalWords() => "1st January 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "12th February 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "22nd March 2015"
// for English US locale
new DateTime(2015, 1, 1).ToOrdinalWords() => "January 1st, 2015"
new DateTime(2015, 2, 12).ToOrdinalWords() => "February 12th, 2015"
new DateTime(2015, 3, 22).ToOrdinalWords() => "March 22nd, 2015"

ToOrdinalWords也支持語法大小寫。 您可以將第二個參數傳遞給ToOrdinalWords以指定輸出的大小寫。 可能的值是GrammaticalCase.Nominative,GrammmicalCase.Genitive,GrammmicalCase.Dative,GrammmicalCase.Accusative,GrammmicalCase.Instrumental和GraammaticalGender。介詞:

顯然,這僅適用於某些文化。 對於其他人來說,通過案例不會對結果產生任何影響。

 

18、羅馬數字

Humanizer可以使用ToRoman擴展名將數字更改為羅馬數字。 數字1到10可以用羅馬數字表示如下:

1.ToRoman() => "I"
2.ToRoman() => "II"
3.ToRoman() => "III"
4.ToRoman() => "IV"
5.ToRoman() => "V"
6.ToRoman() => "VI"
7.ToRoman() => "VII"
8.ToRoman() => "VIII"
9.ToRoman() => "IX"
10.ToRoman() => "X"

也可以使用FromRoman擴展名進行反向操作。

"I".FromRoman() => 1
"II".FromRoman() => 2
"III".FromRoman() => 3
"IV".FromRoman() => 4
"V".FromRoman() => 5

請注意,只有小於4000的整數才能轉換為羅馬數字。

 

19、公制數字
Humanizer可以使用ToMetric擴展名將數字更改為公制數字。 數字1、1230和0.1可以用公制數字表示,如下所示:
1d.ToMetric() => "1"
1230d.ToMetric() => "1.23k"
0.1d.ToMetric() => "100m"

也可以使用FromMetric擴展進行相反的操作。

1d.ToMetric() => "1"
1230d.ToMetric() => "1.23k"
0.1d.ToMetric() => "100m"

"1".FromMetric() => 1
"1.23k".FromMetric() => 1230
"100m".FromMetric() => 0.1

 

20、字節大小

Humanizer包含出色的ByteSize庫的端口。 對ByteSize進行了許多更改和添加,以使與ByteSize的交互更容易且與Humanizer API更加一致。 這是一些如何從數字轉換為字節大小以及在大小幅值之間轉換的示例:

var fileSize = (10).Kilobytes();

fileSize.Bits      => 81920
fileSize.Bytes     => 10240
fileSize.Kilobytes => 10
fileSize.Megabytes => 0.009765625
fileSize.Gigabytes => 9.53674316e-6
fileSize.Terabytes => 9.31322575e-9

有幾種擴展方法可讓您將數字轉換為ByteSize實例:

3.Bits();
5.Bytes();
(10.5).Kilobytes();
(2.5).Megabytes();
(10.2).Gigabytes();
(4.7).Terabytes();

您還可以使用+/-運算符和加/減方法對值進行加/減:

var total = (10).Gigabytes() + (512).Megabytes() - (2.5).Gigabytes();
total.Subtract((2500).Kilobytes()).Add((25).Megabytes());

ByteSize對象包含兩個屬性,它們代表最大的度量標准前綴符號和值:

var maxFileSize = (10).Kilobytes();

maxFileSize.LargestWholeNumberSymbol;  // "KB"
maxFileSize.LargestWholeNumberValue;   // 10

如果要使用字符串表示形式,則可以在ByteSize實例上互換調用ToString或Humanize:

7.Bits().ToString();           // 7 b
8.Bits().ToString();           // 1 B
(.5).Kilobytes().Humanize();   // 512 B
(1000).Kilobytes().ToString(); // 1000 KB
(1024).Kilobytes().Humanize(); // 1 MB
(.5).Gigabytes().Humanize();   // 512 MB
(1024).Gigabytes().ToString(); // 1 TB

您還可以選擇提供期望的字符串表示形式的格式。 格式化程序可以包含要顯示的值的符號:b,B,KB,MB,GB,TB。 格式化程序使用內置的double.ToString方法,將#。##作為默認格式,該格式將數字四舍五入到小數點后兩位:

var b = (10.505).Kilobytes();

// Default number format is #.##
b.ToString("KB");         // 10.52 KB
b.Humanize("MB");         // .01 MB
b.Humanize("b");          // 86057 b

// Default symbol is the largest metric prefix value >= 1
b.ToString("#.#");        // 10.5 KB

// All valid values of double.ToString(string format) are acceptable
b.ToString("0.0000");     // 10.5050 KB
b.Humanize("000.00");     // 010.51 KB

// You can include number format and symbols
b.ToString("#.#### MB");  // .0103 MB
b.Humanize("0.00 GB");    // 0 GB
b.Humanize("#.## B");     // 10757.12 B

如果要使用完整單詞的字符串表示形式,可以在ByteSize實例上調用ToFullWords:

7.Bits().ToFullWords();           // 7 bits
8.Bits().ToFullWords();           // 1 byte
(.5).Kilobytes().ToFullWords();   // 512 bytes
(1000).Kilobytes().ToFullWords(); // 1000 kilobytes
(1024).Kilobytes().ToFullWords(); // 1 megabyte
(.5).Gigabytes().ToFullWords();   // 512 megabytes
(1024).Gigabytes().ToFullWords(); // 1 terabyte

沒有Dehumanize方法可以將字符串表示形式轉換回ByteSize實例。 但是您可以對ByteSize使用Parse和TryParse來做到這一點。 像其他TryParse方法一樣,ByteSize.TryParse返回布爾值,該值指示解析是否成功。 如果解析了該值,則將其輸出到提供的out參數:

 

ByteSize output;
ByteSize.TryParse("1.5mb", out output);

// Invalid
ByteSize.Parse("1.5 b");   // Can't have partial bits

// Valid
ByteSize.Parse("5b");
ByteSize.Parse("1.55B");
ByteSize.Parse("1.55KB");
ByteSize.Parse("1.55 kB "); // Spaces are trimmed
ByteSize.Parse("1.55 kb");
ByteSize.Parse("1.55 MB");
ByteSize.Parse("1.55 mB");
ByteSize.Parse("1.55 mb");
ByteSize.Parse("1.55 GB");
ByteSize.Parse("1.55 gB");
ByteSize.Parse("1.55 gb");
ByteSize.Parse("1.55 TB");
ByteSize.Parse("1.55 tB");
ByteSize.Parse("1.55 tb");

最后,如果您需要計算傳輸一定數量字節的速率,則可以使用ByteSize的Per方法。 Per方法接受一個參數-字節的測量間隔; 這是傳輸字節所花費的時間。

Per方法返回具有Humanize方法的ByteRate類。 默認情況下,速率以秒為單位(例如MB / s)。 但是,如果需要,可以在另一個間隔內將TimeUnit傳遞給Humanize。 有效間隔是TimeUnit.Second,TimeUnit.Minute和TimeUnit.Hour。 下面是每個間隔的示例以及字節率的示例。

var size = ByteSize.FromMegabytes(10);
var measurementInterval = TimeSpan.FromSeconds(1);

var text = size.Per(measurementInterval).Humanize();
// 10 MB/s

text = size.Per(measurementInterval).Humanize(TimeUnit.Minute);
// 600 MB/min

text = size.Per(measurementInterval).Humanize(TimeUnit.Hour);
// 35.15625 GB/hour

您可以為人性化輸出的字節部分指定格式:

 
19854651984.Bytes().Per(1.Seconds()).Humanize("#.##");
// 18.49 GB/s

 

21、角度到單詞

Humanizer包括將數字標題更改為單詞的方法。 標題可以是雙精度,而結果將是字符串。 您可以選擇返回標題的完整表示形式(例如,北,東,南或西),簡短表示形式(例如,N,E,S,W)還是Unicode箭頭字符(例如,↑,→,↓,←) )。

360.ToHeading();
// north
720.ToHeading();
// north

為了檢索標題的簡短版本,您可以使用以下調用:

180.ToHeading(true);
// S
360.ToHeading(true);
// N

請注意,文字表示的最大偏差為11.25°。

最重要的是,這些方法都有一個重載,您可以使用它提供一個CultureInfo對象,以確定要返回的本地化結果。

要檢索表示標題的箭頭,請使用以下方法:

90.ToHeadingArrow();
//
225.ToHeadingArrow();
//

標題的箭頭表示最大偏差為22.5°。

為了檢索基於短文本表示形式的標題(例如N,E,S,W),可以使用以下方法:

"S".FromShortHeading();
// 180
"SW".FromShortHeading();
// 225

 

22、元組化

Humanizer 可以使用Tupleize將整數更改為其“元組”。 例如:

1.Tupleize();
// single
3.Tupleize();
// triple
100.Tupleize();
// centuple

數字1-10、100和1000將轉換為“命名”元組(即“單”,“雙”等)。 任何其他數字“ n”將轉換為“ n元組”。

 

Humanizer 混合到您的框架中以簡化您的生活

這只是一個基礎,您可以使用它來簡化您的日常工作。 例如,在Asp.Net MVC中,我們一直在ViewModel屬性上保留Display屬性,以便HtmlHelper可以為我們生成正確的標簽。 但是,就像枚舉一樣,在大多數情況下,我們只需要在屬性名稱中的單詞之間留一個空格-那么為什么不使用“ string” .Humanize呢?

您可能會在執行該操作的代碼中找到一個Asp.Net MVC示例(盡管該項目已從解決方案文件中排除,從而使nuget包也可用於.Net 3.5)。

這是通過使用名為HumanizerMetadataProvider的自定義DataAnnotationsModelMetadataProvider實現的。 它足夠小,可以在這里重復; 所以我們開始:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web.Mvc;
using Humanizer;

namespace YourApp
{
    public class HumanizerMetadataProvider : DataAnnotationsModelMetadataProvider
    {
        protected override ModelMetadata CreateMetadata(
            IEnumerable<Attribute> attributes,
            Type containerType,
            Func<object> modelAccessor,
            Type modelType,
            string propertyName)
        {
            var propertyAttributes = attributes.ToList();
            var modelMetadata = base.CreateMetadata(propertyAttributes, containerType, modelAccessor, modelType, propertyName);

            if (IsTransformRequired(modelMetadata, propertyAttributes))
                modelMetadata.DisplayName = modelMetadata.PropertyName.Humanize();

            return modelMetadata;
        }

        private static bool IsTransformRequired(ModelMetadata modelMetadata, IList<Attribute> propertyAttributes)
        {
            if (string.IsNullOrEmpty(modelMetadata.PropertyName))
                return false;

            if (propertyAttributes.OfType<DisplayNameAttribute>().Any())
                return false;

            if (propertyAttributes.OfType<DisplayAttribute>().Any())
                return false;

            return true;
        }
    }
}

此類調用基類以提取元數據,然后根據需要使屬性名稱人性化。 它正在檢查屬性是否已經具有DisplayName或Display屬性,在這種情況下,元數據提供程序將僅接受該屬性,而保留該屬性。 對於其他屬性,它將人性化屬性名稱。 就這些。

現在,您需要使用Asp.Net MVC注冊該元數據提供程序。 確保使用System.Web.Mvc.ModelMetadataProviders,而不使用System.Web.ModelBinding.ModelMetadataProviders:

ModelMetadataProviders.Current = new HumanizerMetadataProvider();

...現在您可以替換:

public class RegisterModel
{
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Display(Name = "Email address")]
    public string EmailAddress { get; set; }

    [Display(Name = "Confirm password")]
    public string ConfirmPassword { get; set; }
}

public class RegisterModel
{
    public string UserName { get; set; }
    public string EmailAddress { get; set; }
    public string ConfirmPassword { get; set; }
}

 

...,“元數據人性化工具”將負責其余的工作。

無需提及,如果您想為標簽加上標題框,則可以使用Transform鏈接方法:

modelMetadata.DisplayName = modelMetadata.PropertyName.Humanize().Transform(To.TitleCase);

 

已知的安裝問題和解決方法

由於CLI工具中的錯誤,主要的Humanizer軟件包及其語言軟件包將無法安裝。 作為臨時解決方法,在修復該錯誤之前,請改用Humanizer.xproj。 它包含所有語言。

 

 

GitHub地址:https://github.com/Humanizr/Humanizer


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM