【问题标题】:why js .replace() work incorrectly in double letters?为什么 js .replace() 在双字母中工作不正确?
【发布时间】:2021-03-10 14:33:11
【问题描述】:

我尝试编写在奇怪的情况下返回字符串的函数。例如:

toWeirdCase("String") //StRiNg

所以,它似乎有效,但并非在所有情况下都有效。当我们将字符串与双字母函数返回时,函数会返回一些非常奇怪的东西(没有双精度都很好):

我不需要其他方式来实现,我需要解释我的功能出了什么问题。有人可以吗?

function toWeirdCase(string) {
  let arrSentence = string.toLowerCase().split(' ');
  arrSentence = arrSentence.map((word) => {
    for (let i = 0; i < word.length; i++) {
      if (i % 2 == false) {
        word = word.replace(word[i], word[i].toUpperCase())
      }
    }
    return word
  });
  arrSentence = arrSentence.join(' ');
  return arrSentence
}


console.log(toWeirdCase('Loooooks')) //LOOoooKs
console.log(toWeirdCase('Looks')) //LOokS

【问题讨论】:

  • .replace() 调用不关心i 的值;它会寻找那个特定的字母,并对字符串中找到的第一个字母进行操作。
  • 旁注:我强烈建议从不将数字与truefalse 进行比较。不要使用i % 2 == false。相反,请使用i % 2 === 0。带有布尔值的== 的规则很容易被误解并且难以记住。例如,虽然Boolean(2)true,但2 == truefalse

标签: javascript arrays string replace


【解决方案1】:

正如 Pointy 和 Jared Farrish 所提到的,.replace 与任何其他函数一样,不关心作为参数给出的表达式,它只关心它们被评估的值。考虑以下代码:

var word = 'Loooooks';

console.log(word[0]); // logs 'L'
console.log(word[1]); // logs 'o'
console.log(word[2]); // also logs 'o'
console.log(word[3]); // also logs 'o'

console.log(word[1], word[3]) // logs 'o', 'o'
console.log(word[1] === word[3]); // logs true, different expressions but with equal values

在所示示例中,word[1]word[3] 是表达式,它们的值分别是 'o''o' :D,因为表达式被计算为它们的值,所以:

word = word.replace(word[3], word[3].toUpperCase());

实际上和做的一样:

word = 'Loooooks'.replace('o', 'o'.toUpperCase());

这显然会替换它在字符串中遇到的第一个 'o',生成输出 'LOooooks' 而不是 'LooOooks'

因此,为了替换正确的字符,您可以将单词拆分为一个数组,然后遍历每个字符,替换“奇数”字符(它们在技术上是偶数),然后终于将所有东西重新组合在一起:

// spliting variable word into an array
var splitWord = word.split(''); // ['L', 'o', 'o', 'o', 'o', 'o', 'k', 's']

// iterating over each character, replacing the odd ones
for (let i = 0; i < splitWord.length; i++) {
    if (i % 2 === 0) {
        splitWord[i] = splitWord[i].toUpperCase();
    }
}

// joining everything back together
word = splitWord.join('');
console.log(word); // LoOoOoKs

Jared Farrish 版本基本上是一种更紧凑的方式来做同样的事情。

或者您也可以使用Regular Expressionmatch every pair of characters,然后将每对的第一个字符大写:

// The regex /..?/g matches every pair of characters while
// ignoring the absence of a last character in words with an odd
// number of characters.
word.replace(/..?/g, match => match[0].toUpperCase() + (match[1] || ''));

如果您对非常奇怪的 CaSe 一个短语甚至是一些带有单个替换的多行文本感兴趣,那么您可以使用 /[A-z][^]?/g 来匹配字符对,而不是使用 /..?/g

var text = 'this is\na\tfancy \n\r weird-cased\ntext!';
text = text.replace(/[A-z][^]?/g, match => match[0].toUpperCase() + (match[1] || ''));
console.log(text);

【讨论】:

    【解决方案2】:

    想象一下word = "butter"i=2。然后这一行:

    word.replace(word[i], word[i].toUpperCase())
    

    会将所有出现的t 替换为T,从而得到word = "buTTer"

    【讨论】:

      【解决方案3】:

      这种方法是有问题的,因为正则表达式通常不会按位置替换。我建议改为 reduce。

      const oddify = (odd, letter, pos) => odd + (pos % 2 === 0 ? letter.toUpperCase() : letter)
      const weird = text => text.split('').reduce(oddify, '')
      
      console.log(weird('word'))
      console.log(weird('something'))

      【讨论】:

        猜你喜欢
        • 2017-11-13
        • 1970-01-01
        • 2021-10-15
        • 2019-10-09
        • 2020-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多