【问题标题】:Map and RegEx weirdness [duplicate]地图和正则表达式的怪异[重复]
【发布时间】:2018-02-04 06:12:21
【问题描述】:

我正在做一个将凯撒密码字符串解码为可读文本的 kata。我在地图中使用 RegEx 来查找特殊字符并跳过它们,但是如果我有两个或多个相邻的特殊字符 '、' 或 ' :) ',则输出会很不稳定。它似乎跳过了一些特殊字符。

谁能解释这是怎么回事?

我没有包含 changeCharCode 函数代码,因为我认为问题出在我的地图上。

function decodeString(string) {
  const stringArr = string.toLowerCase().split('');
  const specialCharacters = /[ .,\/#!$%\^&\*;:{}=\-_`~()]/g;
  const codeOfX = 'x'.charCodeAt(0);
  const codeOfLastLetter = stringArr[stringArr.length - 1].charCodeAt(0);
  const codeShift = codeOfX - codeOfLastLetter;

  return stringArr.map((elem) => {
    // Special character treatment
    return specialCharacters.test(elem) === true ? elem : changecharCode(elem, codeShift);
}).join('').toUpperCase();
  }

function changecharCode (letter, codeShift) {
  const currentCode = letter.charCodeAt(0);
  // Uppercase letters
  if ((currentCode >= 65) && (currentCode <= 90))
    return letter = String.fromCharCode(((currentCode - 65 + codeShift) % 26) + 65);
  // Lowercase letters
  else if ((currentCode >= 97) && (currentCode <= 122))
    return letter = String.fromCharCode(((currentCode - 97 + codeShift) % 26) + 97);
}

decodeString(' :) ') => ' ) '
decodeString(', ') => ','

【问题讨论】:

  • specialCharacters.test 对于您在两次调用中提供的每个字符都为真,因为您可以通过调试轻松验证。 “跳过”是什么意思?如果没有changecharCode 函数,我们将无法测试输出。你能提供吗?
  • 为changecharCode添加了你的代码。通过“跳过”,如果它是特殊字符,我希望映射返回元素,那么当您加入映射数组时,特殊字符位于相同的位置。我也不想处理 changecharCode 函数中的特殊字符。是的,你是对的,每个输出的测试调用都返回 true,但是从输出中可以看出,映射的结果并不包括所有特殊字符的元素。
  • 确实,事实证明您的错误出在该函数中。看我的回答。

标签: javascript regex


【解决方案1】:

删除正则表达式末尾的全局标志,您必须一次处理一个字符:

function decodeString(string) {
  const stringArr = string.toLowerCase().split('');
  const specialCharacters = /[ .,\/#!$%\^&\*;:{}=\-_`~()]/;
  //                                              here ___^
  const codeOfX = 'x'.charCodeAt(0);
  const codeOfLastLetter = stringArr[stringArr.length - 1].charCodeAt(0);
  const codeShift = codeOfX - codeOfLastLetter;

  return stringArr.map((elem) => {
    // Special character treatment
    return specialCharacters.test(elem) === true ? elem : changecharCode(elem, codeShift);
}).join('').toUpperCase();
  }

function changecharCode (letter, codeShift) {
  const currentCode = letter.charCodeAt(0);
  // Uppercase letters
  if ((currentCode >= 65) && (currentCode <= 90))
    return letter = String.fromCharCode(((currentCode - 65 + codeShift) % 26) + 65);
  // Lowercase letters
  else if ((currentCode >= 97) && (currentCode <= 122))
    return letter = String.fromCharCode(((currentCode - 97 + codeShift) % 26) + 97);
}

console.log('>'+decodeString(' :) ')+'<');
console.log('>'+decodeString(', ')+'<');

【讨论】:

    【解决方案2】:

    这与why-does-my-javascript-regex-test-give-alternating-results 的问题相同。假设问题的发生是因为g 标志保持全局匹配状态。在您的情况下,解决方案应该是删除 g 标志,一旦您的函数逐个处理字符,则不需要 g 标志。

    【讨论】:

    • 我看到您刚刚删除了标记为bash[ this ] 问题。您介意重新打开,因为我已经为此编写了解决方案。
    【解决方案3】:

    问题出在您的changecharCode 函数中:如果字符代码不在测试的两个范围内,则该函数不返回任何内容,即undefined。您稍后执行的 join 将为每个 undefined 值生成一个空字符串,因此您在输出中看不到任何内容。

    如果你想给changecharCode添加一个final:

    return ' '; // or whatever character you want here
    

    那么输出将具有与输入相同数量的字符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2011-04-15
      • 2016-04-22
      相关资源
      最近更新 更多