【问题标题】:Java - Is there a better substitute for WordUtils.capitalizeFully? Using Strings as delimitersJava - WordUtils.capitalizeFully 有更好的替代品吗?使用字符串作为分隔符
【发布时间】:2020-06-30 16:13:15
【问题描述】:

我正在尝试验证包含名称的字符串,以便它们正确大写。

我正在使用

WordUtils.capitalizeFully(name.trim(), ' ', '-', '\'');

这适用于以下情况:

johN o'Smith => John O'Smith 等

但是是否有一个可用的库,我可以像使用 WordUtils 的字符一样添加字符串作为分隔符? 例如:

Mc (like McAllister)

D' (if followed by non-vowel, like D'Souza)

也许是为了完全避免某些以 Mac 开头的名称的用法 作为

"Macintosh, and Macdonald" are suitably not camel case

yet "MacDowel" is a suitable camel-case word

同样,可能还有更多用例

使用字符串作为分隔符的 decapitalizer,例如:

de/di (if no follow characters.. e.g. John de Smith)

d' (if followed by a vowel) ... YET do ensure that the vowel is capitalised e.g. John d'Agio

现在,我正在研究一个解决方案,其中 a 有一个此类前缀的字符串数组,并通过诸如

之类的常量将它们排序在适当的类别中

final String [] CAPITALISE_FIRST_CHAR_AFTER_THIS_STRING;

随后的 for 循环迭代 split() 名称全名以匹配每个单词与相应常量数组的单词,并应用条件逻辑替换 StringBuilder 实例中的相应后续字符,用大写字母或其他任何情况可能是……等等,但我只是意识到有很多事情要做。

LENGTHY REQUEST 我的道歉,但我希望这有点道理

我看了这个Given Name Formatting,感觉很理想

但我实际上无法查看最佳答案中提供的链接;你也面临这个问题吗?

【问题讨论】:

    标签: java string stringbuilder capitalization


    【解决方案1】:

    这里的根本问题是名称不是那样工作的。

    mcallister -> McAllister 等规则不是全局规则。这是可以应用于苏格兰名称的相关转换。它不能应用于越南名字。

    你基本上是在祈祷不存在冲突。

    不幸的是,存在冲突确实。因此,除非您知道名称所用的语言,否则无法“规范化”名称。您几乎从不这样做;即使它是一个只针对苏格兰公民的应用程序,也有生活在苏格兰的人的名字来源于其他语言。

    我可以给你一个例子:

    在瑞典语中,ö 标准化为 o。在德语中,ö 被标准化为 oe

    干燥综合征也是一种疾病的名称(以瑞典医生的名字命名)。因此,这个名字出现在各种语言环境中,即使你无视瑞典人可以移居德国并在那里定居的想法,如果你将他们的姓氏标准化为 sjoegren 可能会非常生气,因为他们正在使用一个德国网站。

    另一个相关的例子:在荷兰语中,通过忽略中缀来整理姓氏是常见的策略,这在荷兰语中很常见。有人可能会被称为“Jos van Dijk”,“Jos”是他们的名字,“van Dijk”是他们的姓氏。就像苏格兰的 Mc 一样,如果你找到电话簿,Jos 将被排在“Astrid Dijkstra”之前,而不是“Merel Valk”。然而,在美国,许多祖籍荷兰的人都保留了他们的荷兰名字,居住在那里的“Jos van Dijk”会发现自己在“v”下的电话簿中。一样的名字。不同的规则。

    类似的规则适用于 Macintosh:有时,“Macintosh”应该拼写为“Macintosh”并大写。例如,根据苹果公司制造的计算机系列,或以它命名的苹果品种。其他时候,它应该写成'MacIntosh',更常见的是写成'McIntosh'。事实上,虽然在苏格兰,'Mc' 后面总是跟一个大写字母(至少,对于苏格兰血统的名字来说;很难想到以 mc 开头的名字不是祖先的苏格兰语),而对于 'Mac',它是双向的即使是格拉斯哥大学教职员工的姓氏(请参阅 this english stackexchange answer)。

    因此,有些人喜欢麦克阿瑟,有些人喜欢麦克阿瑟。

    因此,如果没有重整名称,规范化方案是不可能。 QED。

    那么,你是如何解决这个困境的呢?

    大多数情况下,你不会。为什么你需要知道一个名字是“适当大写的”?如果不知道该名称所指的实际人,就不可能知道这一点,这可能是您的软件不知道的。为什么重要?

    另一个示例:假设您有一个按用户名搜索的功能,并且您希望此搜索功能在输入“joejackson”时查找“JoeJackson”,或者如果有人输入“Mueller”,您甚至希望查找“Müller”(一个在德国非常普遍的要求)。

    没有任何大小写转换或重音消除将允许Sjogren 等于Sjoegren,但这正是您希望该系统适用于来自不同祖先的姓氏所需要的。但是您可以做的是搜索任何“接近”的用户名,使用一些适当的未命中搜索结构,例如三元组,例如通过 postgres 的pg_trgm system

    但是,rzwitserloot,这听起来太复杂了!

    ¯\(ツ)/¯ 是的,好吧。姓名、日期、地址、时区、性别、旗帜、种族名称 - 如果涉及人类,则往往如此。

    【讨论】:

    • 感谢老兄的回复,我已将 Mc 例外——作为我唯一的字符串“分隔符”,因为我来自那里 - 相当 - 我们的常见姓氏users 替代方案(为了数据库的一致性)可能是我默认情况下将所有内容都大写,因此没有误解的余地但是不,您绝对是对的,任何其他解决方案肯定无法满足 每个人如前所述,我不理会它的主要原因之一是,Mac 是一个常见的前缀,您无法篡改这种用法... MacIntyre,Macey,Macdonald ..那里根本没有关于骆驼肠衣的规定真的
    • 我敢肯定有一些种族名字以 Mc 开头,它不应该期待后续资本。说这是一种耻辱是不正确的,但绝对是一个难以克服的障碍。所有字符的强制大写可能是前进的方向
    【解决方案2】:

    手头有两个问题

    1. 通过验证找到合适的名称
    2. 名字和姓氏都大写

    让我们从第一个开始。 WordUtils 是 Apache Commons 提供的一个强大的库。然而,验证名称(我认为,所有String 对象)的最佳方式是使用Regular Expressions。其次,关于名字的大写,可以将整个字符串小写,然后upper case the first letter

    String name = joHN smITh;
    String[] names = name.split(" "); // first and last name stored in String[]
    
    String lowerCaseFirst = names[0].toLowerCase(); // john
    String first = lowerCaseFirst.subString(0,1).toUpperCase() + lowerCaseFirst.subString(1); // John
    
    String lowerCaseLast = names[1].toLowerCase(); // smith
    String last = lowerCaseLast.subString(0,1).toUpperCase() + lowerCaseLast.substring(1); // Smith
    
    String result = first + last; // John Smith
    

    【讨论】:

      猜你喜欢
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多