【问题标题】:Javascript capitalize first letter of each word in a string only if lengh > 2Javascript仅在长度> 2时才将字符串中每个单词的首字母大写
【发布时间】:2013-06-19 20:26:11
【问题描述】:

我在 StackOverflow 中查看了一些关于大写的问题和答案,但找不到关于我的问题的答案。

仅当单词长度 > 2 时,我想将字符串中每个单词的首字母大写。

我的临时解决方案是:

var str =  str.toLowerCase().replace(/\b[a-z]/g, function (letter) {
                return letter.toUpperCase();
            }).replace(/\b\w{1,2}\b/g, function (letter) {
                return letter.toLowerCase();
            });

有没有办法可以将两个正则表达式合二为一?

【问题讨论】:

  • 在诸如“我想被'titelised'”这样的极端情况下应该发生什么?引用的词是否应该保持不变?
  • 或者其他诸如“第十九修正案”或“train19”之类的,可惜语言不规范。
  • @Xotic750 该功能用于格式化名称。
  • 啊哈,这让我们对你想要达到的目标有了更深入的了解,当然还有很多 2 个字符的名字,尤其是中文,“jo”、“ia”、“li "只是一些例子。所以我认为空白边界在您的用例中就足够了?

标签: javascript regex


【解决方案1】:

这必须做的工作:

str = str.toLowerCase().replace(/\b[a-z](?=[a-z]{2})/g, function(letter) {
    return letter.toUpperCase(); } );

[编辑]

上面的例子有点幼稚,因为它假设字符串中只有字母,并且没有考虑到单词边界\b可以匹配单词字符[a-zA-Z0-9_]和非单词之间的限制角色或锚。因此,为了更严谨,最好这样写:

str = str.toLowerCase().replace(/([^a-z]|^)([a-z])(?=[a-z]{2})/g, function(_, g1, g2) {
    return g1 + g2.toUpperCase(); } );

如果你想这样做,但这次,包括字符串的第一个字母(无论后面的字母数量如何),你可以使用这个:

str = str.toLowerCase().replace(/([^a-z])([a-z])(?=[a-z]{2})|^([a-z])/g, function(_, g1, g2, g3) {
    return (typeof g1 === 'undefined') ? g3.toUpperCase() : g1 + g2.toUpperCase(); } );

【讨论】:

  • 这里不考虑单词的长度是否>2。:)
  • 1.当输入是“我喜欢编码”时,您的输出不正确。 2.当输入是“h3llo yo people”时,你的输出不正确。 3. 当输入为“yooooooo hi”时,您的输出不正确。 4.当输入是“逐字母”时,您的输出不正确。 5.当输入为“a b c d e f”时,您的输出不正确。
  • @KevinGranger: for 1,3,4,5: read the requirements (in the title), for 2: "h3llo" 不是一个词,它是一个词的 leet 形式。
  • 很好的解决方案,虽然它没有解决字符串开头有 1 或 2 个字符的单词的情况(例如“冰与火之歌”)。我相信这个正则表达式可以做到: /(\b[a-z](?=[a-z]{2}))|^[a-z]/g
  • @GageTrader:确实,但请再读一遍这个问题。但是,要做你所说的(如果我理解得很好),你可以使用这个模式:/(\b[a-z](?=[a-z]{2})|^[a-z])/g
【解决方案2】:

试试这个:

var str = str.toLowerCase().replace(/\b\w{3,}/g, function (l) {
    return l.charAt(0).toUpperCase() + l.slice(1);
});

【讨论】:

    【解决方案3】:

    这是一个更简单的解决方案。

    const capitalize = (str) =>
      str.toLowerCase().replace(/\w{3,}/g, (match) =>
        match.replace(/\w/, (m) => m.toUpperCase()));
    

    【讨论】:

      【解决方案4】:

      也许用一个函数让它更干净

      var capitalize1st = function(str){
          str = str || '';
      
          // string length must be more than 2
          if(str.length<3){
              return str;
          }
      
          return str[0].toUpperCase()+str.slice(1);
      }
      
      var splitWordsAndCap1st = function(str){
          str = str || '';
      
          var words = str.match(/\S+/g);
      
          for(var i=0;i<words.length;i++){
              words[i] = capitalize1st(words[i]);
          }
      
          return words.join(' ');
      }
      
      splitWordsAndCap1st("I would like to capitalize first letter of each word in a string");
      

      【讨论】:

      • 这不是 OP 所要求的:只有当单词长度 > 2 时,我才想将字符串中每个单词的首字母大写。
      • 我误解了这个问题。我改变了我的答案,所以现在它解决了问题,你可以随意编辑函数。
      【解决方案5】:

      不需要正则表达式(只需一小部分即可捕获空白),您可以这样做

      Javascript

      function titleCaseLengthGt2(string) {
          var array = string.split(/(\s+)/),
              length = array.length,
              i = 0,
              word;
      
          while (i < length) {
              //array[i] = array[i].toLowerCase(); // make words lowercased first if you want
              word = array[i];
              if (word.length > 2) {
                  array[i] = word.charAt(0).toUpperCase() + word.slice(1);
              }
      
              i += 1;
          }
      
          return array.join("");
      }
      
      console.log(titleCaseLengthGt2("i  want  to  be  titelised"));
      

      输出

      i  Want  to  be  Titelised 
      

      jsfiddle

      【讨论】:

      • 单词边界与空格不同。正则表达式在这里确实有帮助:-)
      • 确实,尽管这是最大的群体,这就是为什么我质疑 OP 认为什么是“词”。无论如何,在这种情况下,即使语言不规则,也需要某种形式的用于拆分“单词”和捕获非“单词”的小型正则表达式/使其更容易。我仍然喜欢尽可能避免使用正则表达式,并将它们用作最后​​的手段(可以这么说):)
      • @whiteb0x 我不知道,为什么不创建一些性能测试并分享结果呢?这有点取决于你在做什么,例如stackoverflow.com/questions/16338714/…
      【解决方案6】:

      如果单词长度> 2,则将字符串中每个单词的首字母大写,我用于英文文本:

      l_text = l_text.toLowerCase().replace(/(?=\b)([a-z])(?=[a-z]{2})/g, 
           function(g0) {return (g0.toUpperCase());});
      

      在现实生活中,规则“字长 > 2”通常是不够的。

      要在法语中大写城镇名称,我必须排除此示例中的一些单词:

      l_text = "Bourg-en-Bresse, NEUILLY SUR SEINE, enghien-les-bains";
      l_text = l_text.toLowerCase().replace(/(?=\b)(?!(?:d|en|les|sous|sur)\b)([a-z])/g,
           function(g0) {return (g0.toUpperCase());});
      

      对于更复杂的情况,您可以将否定前瞻断言 (?!(:|en|les|sous|sur)\b) 和肯定前瞻断言 (?=[a-z]{2}) 结合使用。

      要处理非标准的单词边界和超出 a-z 范围的字符,您可以使用特定于上下文的单词边界和字符集:

      /(?:^|[\s'\-])(?!(?:d|en|les|sous|sur)[\s'\-])([a-zàâéèêïôùûç])/g
      

      【讨论】:

        猜你喜欢
        • 2021-09-07
        • 2020-02-22
        • 2014-06-19
        • 2011-01-20
        • 2014-05-19
        • 2010-12-05
        相关资源
        最近更新 更多