2017-08-26 6 views
2

私は皇帝の暗号列を解読可能なテキストにデコードするkataをやっています。特殊文字を見つけてスキップするためにマップ内でRegExを使用していますが、2つ以上の特殊文字が隣にある場合は出力が不安定です( '、'、 ':)。いくつかの特殊文字を飛ばしているようだ。地図と正規の奇妙さ

誰でも何が起こっているのか説明できますか?

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(', ') => ',' 
+0

'specialCharacters.test'はあなたが提供した各文字に対してtrueになります2つの呼び出しでは、デバッグで簡単に確認できます。 *「スキップオーバー」*とはどういう意味ですか? 'changecharCode'関数を使わないと出力をテストすることはできません。あなたはそれを提供できますか? – trincot

+0

changecharCodeのコードを追加しました。 'スキップオーバー'によって、マップが特殊文字の場合はマップが要素を返すことが期待されます。そのため、マップされた配列に結合するとき、特殊文字は同じ場所にあります。私はまた、changecharCode関数で特殊文字を処理したくありません。 はい、正しいですが、各出力のテスト呼び出しはtrueを返しますが、出力からわかるように、マップの結果には特殊文字である要素のすべてが含まれているわけではありません。 – user6456392

+0

実際、あなたのエラーはその機能にあることが判明しました。私の答えを見てください。 – trincot

答えて

0

それはwhy-does-my-javascript-regex-test-give-alternating-resultsと同じ問題です。グローバルな一致状態を維持するフラグgが原因で問題が発生したとします。あなたの場合の解決策は、gフラグを削除することになっています。関数が文字を1つずつ処理すると、gフラグは不要です。

+0

あなたはあなたが[\ [this \]](https://stackoverflow.com/questions/47495417/shell-script-check-if-data-in-columns-x-from-two-csv-files)を削除しただけです - 一致した)質問は 'bash'とタグ付けされました。私はそれを解決する方法を書いているので、再開してもよろしいですか? – sjsam

0

問題はchangecharCode関数にあります。文字コードがテスト対象の2つの範囲にない場合、関数は何も返しません。つまり、undefinedです。後で行うjoinは、各undefinedの値に対して空の文字列を生成するので、出力には何も表示されません。

あなたはchangecharCodeに最終を追加したい場合:

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

そして、出力が入力と同じ文字数を持つことになります。

1

一度に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(', ')+'<');

関連する問題