2017-08-26 2 views
2

Ich mache eine Kata, die eine Caesar-Chiffre-Zeichenfolge in lesbaren Text dekodiert. Ich benutze RegEx innerhalb einer Map, um Sonderzeichen zu finden und überspringe sie, aber die Ausgabe ist flockig, wenn ich zwei oder mehr Sonderzeichen nebeneinander, ',' oder ':)' habe. Es scheint einige Sonderzeichen zu überspringen.Karte und RegEx-Seltsamkeit

Kann jemand erklären, was vor sich geht?

Ich habe den ChangeCharCode Funktionscode nicht enthalten, weil ich denke, dass das Problem in meiner Karte ist.

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' für jedes Zeichen wahr werden Sie zur Verfügung gestellt haben in den beiden Aufrufen, wie Sie leicht mit dem Debuggen überprüfen können. Was meinst du mit * "Überspringen" *? Wir können die Ausgabe nicht ohne die 'chitcharCode'-Funktion testen. Könnten Sie es bereitstellen? – trincot

+0

Der Code für choecharCode wurde hinzugefügt. Mit 'Überspringen' erwarte ich, dass die Karte das Element zurückgibt, wenn es ein Sonderzeichen ist. Wenn Sie also dem abgebildeten Array beitreten, befinden sich die Sonderzeichen an denselben Stellen. Ich möchte auch nicht das Sonderzeichen in der chitcharCode-Funktion behandeln. Ja, Sie haben recht, die Testaufrufe für jeden Ausgang gibt true zurück, aber wie Sie aus der Ausgabe sehen können, enthält das Ergebnis der Karte nicht alle Elemente, die Sonderzeichen sind. – user6456392

+0

In der Tat, es stellt sich heraus, dass Ihr Fehler in dieser Funktion ist. Siehe meine Antwort. – trincot

Antwort

0

Es ist das gleiche Problem wie why-does-my-javascript-regex-test-give-alternating-results. Nehmen wir an, dass das Problem wegen des Flags g aufgetreten ist, das einen globalen Übereinstimmungsstatus beibehält. Die Lösung in Ihrem Fall soll sein, ein g Flag zu entfernen, sobald Ihre Funktion Zeichen nacheinander ausführt, dann ist das g Flag unnötig.

+0

Ich sehe, dass Sie gerade [\ [this \]] gelöscht haben (https://stackoverflow.com/questions/47495417/shell-script-check-if-data-in-columns-x-from-two-csv-files -are-matched) Frage, die mit 'bash' getaggt wurde. Würde es Ihnen etwas ausmachen, wieder zu öffnen, wie ich eine Lösung dafür geschrieben habe? – sjsam

0

Das Problem ist in Ihrer changecharCode Funktion: Wenn ein Zeichencode nicht innerhalb der zwei Bereiche ist, die getestet werden, dann gibt die Funktion nichts zurück, d. H. . Die join, die Sie später machen, wird eine leere Zeichenkette für jeden undefined Wert erzeugen, so dass Sie nichts in der Ausgabe sehen.

Wenn Sie hinzufügen, ein Finale zu changecharCode:

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

Dann ist der Ausgang die gleiche Anzahl von Zeichen, die als Eingang haben.

1

Entfernen Sie die globale Flagge am Ende der Regex, haben Sie ein Zeichen in einer Zeit zu gehen:

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