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");
Related
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)
}
}
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,'');
I have a bunch of strings to match for Bonfire: Palindrome in FreeCodeCamp
The strings are:
eye
racecar
not a palindrome
A man, a plan, a canal. Panama
nope
almostomla
My age is 0, 0 si ega ym.
1 eye for of 1 eye.
0_0 (: /-\ :) 0-0
My Code:
function palindrome(str) {
var newstr = str.replace(/[^\w_-]/g,"").toLowerCase();
var num = newstr.length;
for(var i=0;i<=Math.floor(num/2);i++)
{
if(newstr[i]!==newstr[num-i])
{
return newstr;
}
}
return true;
}
What could be wrong in the if statement? the return of the string is alright.. Just can't wrap my head around these Regular expressions?
My current regular expression:
var newstr = str.replace(/[^\w_-]/g,"").toLowerCase();
matches almost all the strings but the last one. Where am I going wrong?
The last one is not a palindrome; you have 0_0 at the beginning, 0-0 at the end, and do not erase those characters.
As a pedantic note, this is not, strictly speaking, a regular language.
Indexes in an array or string run from 0 to length-1. But when you access the elements at the end of the string, you're going from num, not num-1. You need to subtract an additional 1 when you subtract from the end. So it should be:
if (newstr[i] != newstr[num-i-1]) {
return newstr;
}
So while the answers were useful, they did not provide a correct regular expression. Shoot out to #Barmar for pointing at the right direction. This is my regular expression.
var newstr = str.replace(/[\W_]/g,'').toLowerCase();
The full code for Palindrome in FCC:
function palindrome(str) {
var newstr = str.replace(/[\W_]/g,'').toLowerCase();
var num = newstr.length;
for(var i=0;i<=Math.floor(num/2);i++)
{
if(newstr[i]!==newstr[num-1-i])
{
return false;
}
}
return true;
}
palindrome("0_0 (: /-\ :) 0-0");
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
How can I quickly validate if a string is alphabetic only, e.g
var str = "!";
alert(isLetter(str)); // false
var str = "a";
alert(isLetter(str)); // true
Edit : I would like to add parenthesis i.e () to an exception, so
var str = "(";
or
var str = ")";
should also return true.
Regular expression to require at least one letter, or paren, and only allow letters and paren:
function isAlphaOrParen(str) {
return /^[a-zA-Z()]+$/.test(str);
}
Modify the regexp as needed:
/^[a-zA-Z()]*$/ - also returns true for an empty string
/^[a-zA-Z()]$/ - only returns true for single characters.
/^[a-zA-Z() ]+$/ - also allows spaces
Here you go:
function isLetter(s)
{
return s.match("^[a-zA-Z\(\)]+$");
}
If memory serves this should work in javascript:
function containsOnlyLettersOrParenthesis(str)
(
return str.match(/^([a-z\(\)]+)$/i);
)
You could use Regular Expressions...
functions isLetter(str) {
return str.match("^[a-zA-Z()]+$");
}
Oops... my bad... this is wrong... it should be
functions isLetter(str) {
return "^[a-zA-Z()]+$".test(str);
}
As the other answer says... sorry