Palindrome Checker in JavaScript - don't know how to debug - javascript

I want to build a palindrome checker in javascript. All non-letter characters should be removed, so that a phrase like "A man, a plan, a canal. Panama" can also be a palindrome.
function reverse(str) {
return str.split("").reverse().join("");
}
function palindrome(str) {
str = str.replace(/[^a-zA-Z]+/,"").toLowerCase();
if(str == reverse(str)) {
return true;
}
else {
return false;
}
}
Now, where is the mistake in the above lines?
The code works on some examples. But for instance "A man, a plan, a canal. Panama" and "never odd or even" return false, meaning somewhere has to be a mistake.

You need to provide the global match flag to your regex:
/[^a-zA-Z]+/g
^

This is a common misconception. The replace() method does not replace all instances of what you want to replace in a string. It simply replaces the first instance and stops. If you refactor your regEx like this:
function reverse(str) {
return str.split("").reverse().join("");
}
function palindrome(str) {
var find = "[^a-zA-Z]";
var regEx = new RegExp(find, 'g');
str = str.replace(regEx,"").toLowerCase();
if(str == reverse(str)) {
return true;
}
else {
return false;
}
}
That will work.

From the example given, it seems to me that the code doesn't work for spaces in between the letters. (There may be other scenarios as well)
I have changed this line :
str = str.replace(/[^a-zA-Z]+/,"").toLowerCase();
To this :
str = str.toLowerCase().replace(/[^a-z]/g,"");

change this line:
str = str.replace(/[^a-zA-Z]+/,"").toLowerCase();
to this:
str = str.toLowerCase().replace(/[^a-z0123456789]+/g,"");

This regex should work for your code.
/[^1-9a-zA-Z]+/g

Related

Algorithm - Search and Replace a string

I am doing a algorithm in freeCodeCamp.(https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/search-and-replace)
The task is as below:
Perform a search and replace on the sentence using the arguments provided and return the new sentence.
First argument is the sentence to perform the search and replace on.
Second argument is the word that you will be replacing (before).
Third argument is what you will be replacing the second argument with (after).
Note:
Preserve the case of the first character in the original word when you are replacing it. For example if you mean to replace the word "Book" with the word "dog", it should be replaced as "Dog"
**
myReplace("Let us get back to more Coding", "Coding", "algorithms") should return "Let us get back to more Algorithms".
myReplace("Let us go to the store", "store", "mall") should return "Let us go to the mall".
**
//if the before is uppercase, the after should be uppercase also
// str = str.replace(before, after);
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
console.log(regex.test(before));
if (regex.test(before)) {
//if uppercase, return true, "after" convert to uppercase
after = after.toUpperCase();
newStr = after[0];
for (var i = 1; i < after.length; i++) {
//start at index=1 letter, all convert to
newStr += after[i].toLowerCase();
}
console.log(newStr);
str = str.replace(before, newStr);
} else {
str = str.replace(before, after);
}
// console.log(newStr);
console.log(str);
return str;
}
I think there should be OK for the code, but can anyone help find why the if statement can't work.
Much thanks!
The problem is that you're calling regex.test() multiple times on the same regular expression instance.
[...]
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
console.log(regex.test(before));
if (regex.test(before)) {
//if uppercase, return true, "after" convert to uppercase
after = after.toUpperCase();
[...]
If your string is Hello_there, the first regex.test() will return true, because Hello matched. If you call regex.test() again with the same regex instance, it will have advanced in the string, and try to match starting with _there. In this case, it will fail, because _there does not begin with a capital letter between A and Z.
There are a lot of ways to fix this issue. Perhaps the simplest is to store the result of the first call to a variable, and use it everywhere you're calling regex.test():
[...]
var regex = /[A-Z]+/g; //check for uppercase
var newStr = "";
var upper_check = regex.test(before);
console.log(upper_check);
if (upper_check) {
[...]
It seems overkill to use a regex, when you really need to only check the first character. Your regex will find uppercase letters anywhere...
If the assignment is to only change one occurrence, then a regex is not really the right tool here: it does not really help to improve the code nor the efficiency. Just do:
function myReplace(str, before, after) {
if (before[0] === before[0].toUpperCase()) {
after = after[0].toUpperCase() + after.slice(1);
} else {
after = after[0].toLowerCase() + after.slice(1);
}
return str.replace(before, after);
}
function myReplace(str, before, after) {
var upperRegExp = /[A-Z]/g
var lowerRegExp = /[a-z]/g
var afterCapitalCase = after.replace(/^./, after[0].toUpperCase());
if (before[0].match(upperRegExp)) {
return str.replace(before, afterCapitalCase)
} else if (after[0].match(upperRegExp) && before[0].match(lowerRegExp)) {
return str.replace(before, after.toLowerCase());
} else {
return str.replace(before, after)
}
}

palindrome regex

function palindrome(str) {
// Good luck!
var a = str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
palindrome("eye");
palindrome("1 eye for of 1 eye.") //should return false.
I have done this task on freecodecampus.com. Can anyone tell me why it should give false? If we are removing dot and punctuations, then isn't it right that it should return true?
According to your comment "Note You'll need to remove all non-alphanumeric characters (punctuation, spaces and symbols)", you have to keep alphanumeric characters (ie. letters AND digits). So remove NON alphanum characters (ie. [\W_]). \W is the negation of \w: [^a-zA-Z0-9_]
This is done with:
var test = [
"racecar",
"RaceCar",
"race CAR",
"2A3*3a2",
"2A3 3a2",
"2_A3*3#A2",
"1 eye for of 1 eye."
];
function palindrome(str) {
var a = str.replace(/[\W_]+/g, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
console.log(test.map(function (a) {
return a+' : '+palindrome(a);
}));
function palindrome(str) {
// Good luck!
var a = str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "").toLowerCase();
// Here print a
// a = "eyeforofeye"; which is perfect palindrome
if (a === a.split("").reverse().join("")) {
// will pass this condition
return true;
}
return false;
}
palindrome("1 eye for of 1 eye.")
See my comments in the code. The replace method is using a regex to replace all numbers, special character and spaces with nothing. So all you get is a single word with no spaces, numbers and special characters.
In your case you will get eyeforofeye which is perfect palindrome.
You are doing a Rube Goldberg process by providing an overly complicated Regular Expression which could be shorten to /[^a-z]/ and it doesn't return false if you execute your code.
function palindrome(str) {
var a = str.replace(/[^a-z]/ig, '').toLowerCase();
return a === a.split('').reverse().join('');
}
console.log(palindrome('race CAR'));
console.log(palindrome('2A3 3a2'));
console.log(palindrome('eye'));
console.log(palindrome('1 eye for of 1 eye.'));
console.log(palindrome('stack'));
Thanks a lot folks, have done it; Also got some good information on RegeXes. Reading RegEx from Eloquent Javascript, can anyone suggest another better source? Thanx ahead
By the Way As an Answer it took this, ( for those who are interested in answer that passes all ticks in project) ,
function palindrome(str) {
// Good luck!
var a = str.replace(/[^a-z0-9]/ig, "").toLowerCase();
if (a === a.split("").reverse().join("")) {
return true;
}
return false;
}
palindrome("eye");

Why won't my JS code filter out this "_" element from string?

I'm working on the FreeCodeCamp Front End Development Certification and have arrived at the Basic Algorithm Scripting part. One of the exercises is to write a code that tests for palindromes. I understand everything (well almost) that is to be done, have quickly written my code but cannot understand why it doesn't give the correct result for strings containting underscores (_). Here is my code:
function palindrome(str) {
str = str.replace(/\W/g,'');
if ((((str.toLowerCase()).split("")).reverse()).join("") == str.toLowerCase()){
return true;
}
else {
return false;
}
}
palindrome("_eye");
The \W in regex is basically a short way to write "every chat that is not any of the [a-zA-Z0-9_] chars".
As you you can see - digits and underscore are also part of that.
If you to remove every char that is not [a-zA-Z] you can use /[^a-zA-Z]/ instead:
function palindrome(str) {
str = str.replace(/[^a-zA-Z]/g,'');
if ((((str.toLowerCase()).split("")).reverse()).join("") == str.toLowerCase()){
return true;
}
else {
return false;
}
}
console.log(palindrome("_eye"))
Just change yout regex to str.replace(/[\W_]/g,'');

Javascript regex for palindrome?

<code>
function palindrome(str) {
// Good luck!
str=str.toLowerCase();
str=str.replace(/[^\Wa-z0-9]/gi," ");
str=str.replace(/[.,\s]/g, '');
str=str.replace(/\//g, "");
str=str.replace("(", "").replace(")", "").replace("0-0", "").replace(":-", "").replace(":","");
var a=str.split("");
a=a.reverse();
a=a.join("");
if(str===a){
return true;
}
else {
return false;
}
}
palindrome("0_0 (: /-\ :) 0-0");
</code>
Note : I am trying here to remove all the special characters,spaces, and uppercase character and checking that if the passed argument is palindrome or not. I just want to know if there is a way to make the regex concise to only one line.
str = str.toLowerCase().replace( /[^a-z0-9]/g, '' );
Will lowercase the string and remove all non alphanumeric characters.

JavaScript Check for palindrome (spaces & punctuation included)

Trying to check for palindromes. I've checked other answers but none included punctuation & spaces.
"never odd or even" and "A man, a plan, a canal. Panama" Should return true but they don't.
function palindrome(str) {
if(str.replace(/[^\w\s]|_/g, "").toLowerCase() === str.replace(/[^\w\s]|_/g, "").toLowerCase().split("").reverse().join("")){
return true;
} else {
return false;
}
}
palindrome("eye");
I think you have an error in your RegEx. If you want to remove the spaces, you don't need that \s. Try changing:
str.replace(/[^\w\s]|_/g, "")
With
str.replace(/[^\w]|_/g, "")
Use instead:
str.replace(/\W/g, "")
Which will replace any non-word char by empty string.
You can try with a simpler regex which simply replaces any character that is not in the alphabet?
function palindrome(str) {
if(str.replace(/[^a-zA-Z]/g, "").toLowerCase() === str.replace(/[^a-zA-Z]/g, "").toLowerCase().split("").reverse().join("")){
return true;
} else {
return false;
}
}
This is similar to the above but reformatted:
function palindrome(str) {
let regex = /[^a-zA-Z]/g;
return str.replace(regex, '').toLowerCase() === str.replace(regex, '').toLowerCase().split('').reverse().join('');
}

Categories