Humanizer 操作和展示以下类型的需求,包括字符串、枚举、日期、时间、时间跨度、数字和数量。

一、使用:直接NuGet直接搜索Humanizer 下载即可

 

 

 

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
      
参考:https://www.xin3721.com/articlecsharp/net19608.html
posted @ 2022-03-07 18:47  bkyvoid  阅读(176)  评论(0编辑  收藏  举报