【问题标题】:(replace) CamelCase function not work properly(替换) CamelCase 函数不能正常工作
【发布时间】:2019-06-25 16:43:26
【问题描述】:

使用此函数调用:

var StringData = window.ToCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
console.log(StringData);

这是我的脚本函数:

function ToCamelCase(data) {
    data['string'] = data['string'].replace(/(?:^\w|[A-Z]|\b\w)/g, function(word, index) {
        return index == 0 ? word.toUpperCase() : word.toLowerCase();
    });
    if (data['remSpace']) {
        data['string'] = data['string'].replace(/\s/g, '');
    }
    return data['string'];
}

我没有收到错误;但不能正常工作,如果我通过了这样的字符串:

"HELLO WORLD"

此时第二个单词不把第一个字母大写

输出是:"Hello world",我期望:"Hello World"

每个单词的第一个字母大写,后面的小写是规则。

我做错了什么?

【问题讨论】:

  • 字符串是不可变的。 replace() 确实 *not * 修改使用它的字符串。它返回 修改后的字符串,您没有捕获该字符串。考虑data['string'] = data['string'].replace(...)
  • 我已经修改了问题。
  • 此时第二个单词没有把第一个字母大写
  • @Teemu 是真的,不需要删除空间...
  • @TylerRoper 我已经更新了功能和问题...

标签: javascript replace


【解决方案1】:

您实际上并不需要为此使用正则表达式。您可以使用string.split() 拆分字符串,然后将拆分数组中的每个元素大写。最后,如果需要,可以将数组与分隔元素的空格重新组合:

function ToCamelCase(data) {
    const words = data['string'].toLowerCase().split(' ');
    const uppercasedWords = words.map(word => {
        let splitWord = word.split('');
        splitWord[0] = splitWord[0].toUpperCase();
        return splitWord.join('');
    });
    return uppercasedWords.join(data['remSpace'] ? '' : ' ')
}

或更多功能,

function uppercaseFirstElement(textArray) {
    return [textArray[0].toUpperCase(), ...textArray.slice(1)];
}

function capitalizeWord(word) {
    return uppercaseFirstElement(word.split('')).join('');
}

function toCamelCase(sentence, removeSpace) { // Really it should be `toPascalCase`
    return sentence.toLowerCase().split(' ')
        .map(capitalizeWord).join(removeSpace ? '' : ' ');
}

【讨论】:

  • 为什么用 let 而不是 var?
  • 一个简短的说明,如果你把整个字符串小写之前split它,你就不必每次迭代都调用toLowerCase() :) 东西@ 987654321@.
  • @walternuñez 现代 JavaScript(从版本 es6 开始,所有最近的浏览器都支持)将关键字 letconstlet 的恒定版本)添加到语言中。这些关键字使用起来更安全,因为它们创建块范围的变量而不是函数范围的变量,它们不会提升变量,并且它们不允许重新声明相同的变量。这些都是有些高级的话题,所以我建议对它进行一些研究,但简而言之,letconst 更安全、更可预测。
【解决方案2】:

正如 Ian 所说,您不需要正则表达式来完成这项工作,不使用它们可能更有效。

话虽如此,如果您出于某种原因确实想让它与 RegExp 一起使用,您可以使用:

function toPascalCase(str) {
    return str.replace(/(?:^|\s*)(\S+)(?:\s*|$)/g, (match, word) => word[0].toUpperCase() + word.slice(1).toLowerCase());
}

此代码使用 es6 箭头功能,因此如果您想与旧浏览器兼容,则需要对其进行更改。这也是基于我可以从您的问题中获得的规范,但是对于字母/数字/空格范围之外的特殊字符,有很多大小写未处理(它们将被视为单词的一部分 - 这可能是您想要的不过)。

最后一点:您要实现的实际上称为 PascalCase。在 camelCase 中,第一个字母是小写的。

【讨论】:

    【解决方案3】:

    首先Ian's solution 应该是正确的,因为它是所有解决方案中最简单易懂的。

    如果你问你的代码有什么问题,那么我的回答是:

    index == 0 ? word.toUpperCase() : word.toLowerCase()

    这句话是什么导致了所有问题。当您的索引达到"W""World" 时,您的索引不是0,所以它会变成小写。

    相反,您应该做的是捕获单词并将每个单词的第一个字母替换为大写。 Split 方法是一个很好的解决方案,这就是 Ian 所做的。我已经使用正则表达式和替换做了类似的事情,尽管没有必要这样做。

    function ToCamelCase(data) {
        data['string'] = data['string'].replace(/(?:\s|^)(\w+)(?=\s|$)/g, function(word, index) {
            var lowerWord = word.toLowerCase().trim();
            return lowerWord.substring(0, 1).toUpperCase() + lowerWord.substring(1, word.length) + " "
        });
        if (data['remSpace']) {
            data['string'] = data['string'].replace(/\s/g, '');
        }
        return data['string'];
    }
    

    【讨论】:

      【解决方案4】:

      在您的代码中,索引将始终返回 0,因为它不会迭代您的所有字符串字符 在这里,我尝试使用我的代码替换为您的代码并让我知道结果。

      var StringData = window.toCamelCase({ 'string': 'HELLO WORLD', 'remSpace': false });
      console.log(StringData);
      
      function toCamelCase(data) {
       var str = data['string'];
       var isRemoveSpc = data['remSpace'];
       var len = data['string'].length;
       var newStr = "";
       for(var i = 0; i < len; i++){
        if( i == 0) {
         newStr += str.charAt(i).toUpperCase();
        } else if(str.charAt(i) == " ") {
         if(isRemoveSpc) {
          i++;
          newStr += str.charAt(i).toUpperCase();
         } else {
          newStr += str.charAt(i);
          i++;
          newStr += str.charAt(i).toUpperCase();
        }  
       } else {
         newStr += str.charAt(i).toLowerCase();
       }
      }
        return newStr;
      }
      
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-20
        • 1970-01-01
        • 1970-01-01
        • 2018-06-17
        • 2013-04-09
        • 1970-01-01
        相关资源
        最近更新 更多