<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.
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)
}
}
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");
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
Trying to make sure no one put a space in the username on sign up, I got the html tags to removed but not spaces.
Javascript:
$("#user").keypress(function (evt) {
if (isValid(String.fromCharCode(evt.which)))
return false;
});
function isValid(str) {
return /[~`!#$%\^&*+=\-\[\]\\';,/{}|\\":<>\?]/g.test(str);
}
function stripspaces(input) {
input.value = input.value.replace(/\s/gi, "");
return true;
}
HTML:
Username: <input type="text" id="user"><br/>
You can see it here. http://jsfiddle.net/QshDd/63/
You can try with (each space character is being replaced, character by character, with the empty string):
str = str.replace(/\s/g, '');
or (each contiguous string of space characters is being replaced with the empty string by the "+" character):
str = str.replace(/\s+/g, '');
Ciao!
try this,
input.value.replace(/\n/g," ").replace( /<.*?>/g, "" );
You need to return the input value with the spaces removed:
function stripspaces(input)
{
return input.value.replace(/\s/gi,"");
}
The way you had it written the function just returned true regardless. Also, it seems you weren't calling the function (admittedly from only a quick read).
Although, it's probably easier to simply add \s (a regular expression special character for white-space characters) to the characters to replace, giving:
function isValid(str) {
return /[~`!#$%\^&*+=\-\[\]\\';,/\s{}|\\":<>\?]/g.test(str);
}
JS Fiddle demo.
References:
JavaScript regular expressions.
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