如何在JavaScript中将名称转换为标题格式?

4

我一直在寻找如何使用JavaScript将名称设置为正确的大小写,例如george mchall会变成George McHall。我能够在Codeproject上找到有关如何实现此目标的文章,以及一个人打算这样做:

function toProperCase(s){
    return s.toLowerCase().replace( /\b((m)(a?c))?(\w)/g,
    function($1, $2, $3, $4, $5) {
  if($2){
   return $3.toUpperCase()+$4+$5.toUpperCase();
  } 
  return $1.toUpperCase(); 
 });
}

这可以满足我的需求。但我需要进一步扩展并添加其他情况。
我在John Gruber网站上找到了另一个页面,它使用标题大小写,但我只想处理名称。
所以,有人有扩展它的想法吗?我只是需要指点方向。
编辑: 由于我似乎遇到了瓶颈,也许有人知道如何在服务器端执行此操作。目前至少使用ColdFusion进行服务器端操作。我见过C#实现,但我暂时无法转换到C#。

5
这个问题比起初看起来要复杂得多。你需要考虑除Mac/Mc之外的情况,例如O'Brien、D'Agostino和LaSalle等。正则表达式可能不是最好的工具。你可能需要使用某种字典。 - Robusto
还要考虑各种拉丁名字,比如“Oscar de la Renta”,其中“de”和“la”不应该大写。 - T.J. Crowder
1
@Tim:问题在于区分像Lasseter和LaSalle这样的姓氏。这是无法通过正则表达式实现的。 - Andy E
@Tim:是的,那听起来像是一个可行的替代方案。通常,那些名字大小写奇怪的人会非常在意大小写,并确保他们在在线表单中正确地输入它。如果你只修复全小写或全大写,你就减少了“修复”一些本来没问题的东西的可能性。 - Andy E
1
@Tim Meers:我又想到了一个棘手的例外。谷歌搜索“Jerald terHorst”,他是杰拉尔德·福特的新闻秘书。我认为你会发现用正则表达式没有“完美”的方法来完成这个任务。 - Robusto
显示剩余6条评论
2个回答

6

从类似帖子中结合几个答案:

    var selElem = document.getElementById("fromName");

    selElem.addEventListener("change", function() {
      document.getElementById("result").innerHTML = properName(selElem.value);
    });

    function properName(name) {
      return ("" + name.replace(/[^\s\-\']+[\s\-\']*/g, function(word) {
        return word.charAt(0).toUpperCase() + word.substr(1).toLowerCase();
      }).replace(/\b(Van|De|Der|Da|Von)\b/g, function(nobiliaryParticle) {
        return nobiliaryParticle.toLowerCase();
      }).replace(/Mc(.)/g, function(match, letter3) {
        return 'Mc' + letter3.toUpperCase();
      }));
    }
<p>
  Choose a name to see it properly capitalised:
</p>
<select id="fromName">
  <option>Select a name</option>
  <option>EMMA HURST</option>
  <option>CHRIS HINDI</option>
  <option>OSCAR GRENFELL</option>
  <option>JIM CASEY</option>
  <option>MEOW-LUDO DISCO GAMMA MEOW-MEOW</option>
  <option>PAT SHEIL</option>
  <option>NOEL MCFARLANE</option>
  <option>CHRIS MCLACHLAN</option>
  <option>ANTHONY ALBANESE</option>
  <option>DAVID VAN GOGH</option>
  <option>JAMIE ELVY</option>
</select>
<p>Result: <span id="result"></span></p>


3
这个怎么样?
if (str==str.toLowerCase() || str==str.toUpperCase())
  str = str.toTitleCase();

否则,请不要去碰它!!!
编辑:你可以选择将字符串拆分,以排除像SMith这样长时间按住Shift键的人。

在问题评论中进行讨论后,这是“最佳”解决方案。然而 toTitleCase() 对我来说根本不起作用。也许详细说明你的答案会有所帮助。 - Tim Meers
抱歉,我以为这是一个内置函数。这里有一个实现代码可以让它工作:http://individed.com/code/to-title-case/js/to-title-case.js - Nathan MacInnes
我选择这个答案,因为它“足够好”,并且应该至少尝试捕捉似乎是最广泛的违规组的大写锁定违规者。 - Tim Meers
是的,在使用PHP时,我发现“够好”就可以了。因为不可能考虑到每一个可能的混合大小写的姓氏。 - Nathan MacInnes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接