I'd like to make the following code case-insensitive. If I test it out with
isSuffix("Albatross", "Ross")
it returns false, but if I try
isSuffix("Albatross", "ross")
it returns true.
How do I make it case-insensitive?
function isSuffix(str, suffix) {
if (str.substring(str.length - suffix.length) == suffix) {
return true;
return false;
}
Change your code to this (which makes use of .toLowerCase()
function isSuffix(str, suffix) {
return (str.substring(str.length - suffix.length).toLowerCase() == suffix.toLowerCase());
}
You can do this with regular expressions:
function isSuffix(str, suffix) {
var regSuffix = new RegExp(suffix + '$', 'i');
if ( regSuffix.test(str) ) {
return true;
}
return false;
}
Just use the toLowerCase function.
function isSuffix(str, suffix) {
str = str.toLowerCase();
if (str.substring(str.length - suffix.length) == suffix.toLowerCase()) {
return true;
}
return false;
}
You can use String.toLowerCase()
function isSuffix(str, suffix) {
if (str.substring(str.length - suffix.length).toLowerCase() == suffix.toLowerCase())
return true;
return false;
}
alert(isSuffix("Albatross", "Ross"))
You could use a regular expression, too, but this is closer to your original code.
Unless you can use case insensitive regular expression match with "i" (when suffix is either just text or cost of escaping worth it) you have to convert strings to lower case first before searching. Depending on your operations per-converting one or both to lower case may give better performance if you need to perform a lot of searches.
Creating new string to simply check if suffix matches could also be wasteful. For ancient browsers you can use lastIndexOf after converting string to lower case with toLowerCase.
For more modern JavaScript code (current versions of browsers/NodeJS) use endsWith (the link also includes polyfill):
function isSuffix(str, suffix) {
return (str.toLowerCase().endsWith(suffix.toLowerCase());
}
Related
I have a regex which checks the inputText is in valid url format or not.
And working almost good:
checkUrlFormat() {
const pattern = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/;
if (pattern.test(this.inputText) || this.inputText == null) {
return false;
}
return true;
}
But i need to make that pattern shorter so I have written a regexp in https://www.debuggex.com/#cheatsheet as
(((http|https)(://))?((www).)?)[a-z0-9]+(.|[a-z0-9])+[a-z0-9]
but it is in javascript format and i could not find how to use that string with the code above. When i directly copy paste it, it is giving syntax error. How can i combine them.
checkUrlFormat() {
const pattern = /^(((http|https)(:\/\/))?((www).)?)[a-z0-9]+(.|[a-z0-9])+[a-z0-9]$/;
if (pattern.test(this.inputText) || this.inputText == null) {
return false;
}
return true;
}
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 have just started to learn functions and am finding it quite difficult.
I have learnt a few different functions but I haven't ever done a function like this.
How do I write a function called validate(z) which takes a string as an argument and returns true if it contains one # symbol and at least one dot . and false otherwise.
E.g. if z = "stack#overflow.co.uk" the function will return true.
Regex seems like a lot of overkill for such a simple requirement. I'd go with something like this
function validate(z) {
var hasDots = z.indexOf('.') !== -1,
firstAt = z.indexOf('#'),
lastAt = z.lastIndexOf('#');
return hasDots && firstAt !== -1 && firstAt === lastAt;
}
It sounds like what you're looking for is an email validation function. These are a lot more tricky to write than you may expect. You have to validate length as well as format. Here's one that's worked well for me in all of my implementations using a (quite complicated) regex statement.
function validateEmail(v) {
var r = new RegExp("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
return (v.match(r) == null) ? false : true;
}
You can use regex.
function validate(z) {
var re = /^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
return re.test(z);
}
For the dot, use indexOf to search for the character in the input:
function contains(z, c) {
return z.indexOf(c) !== -1;
}
To check for a single #, you could say
function contains_one(z, c) {
var first = z.indexOf(c);
var last = z.lastIndexOf(c);
return first !== -1 && first == last;
}
function validate(z) {
return contains_one(z, '#') && contains(z, '.');
}
If you prefer to use regexp:
function validate(z) {
return /^[^#]*#[^#]*\.[^#]*$/.test(z);
}
This says asks for a sequence of non-at-signs, followed by an at-sign, followed by a sequence of non-at-signs, followed by a dot, followed by a sequence of non at signs. You may want to tweak this. For instance, it insists that the dot be to the right of the at sign. Also, it allows the dot to come immediately after the at-sign, or immediately at the end of the input.
Can anyone tell me why does this not work for integers but works for characters? I really hate reg expressions since they are cryptic but will if I have too. Also I want to include the "-()" as well in the valid characters.
String.prototype.Contains = function (str) {
return this.indexOf(str) != -1;
};
var validChars = '0123456789';
var str = $("#textbox1").val().toString();
if (str.Contains(validChars)) {
alert("found");
} else {
alert("not found");
}
Review
String.prototype.Contains = function (str) {
return this.indexOf(str) != -1;
};
This String "method" returns true if str is contained within itself, e.g. 'hello world'.indexOf('world') != -1would returntrue`.
var validChars = '0123456789';
var str = $("#textbox1").val().toString();
The value of $('#textbox1').val() is already a string, so the .toString() isn't necessary here.
if (str.Contains(validChars)) {
alert("found");
} else {
alert("not found");
}
This is where it goes wrong; effectively, this executes '1234'.indexOf('0123456789') != -1; it will almost always return false unless you have a huge number like 10123456789.
What you could have done is test each character in str whether they're contained inside '0123456789', e.g. '0123456789'.indexOf(c) != -1 where c is a character in str. It can be done a lot easier though.
Solution
I know you don't like regular expressions, but they're pretty useful in these cases:
if ($("#textbox1").val().match(/^[0-9()]+$/)) {
alert("valid");
} else {
alert("not valid");
}
Explanation
[0-9()] is a character class, comprising the range 0-9 which is short for 0123456789 and the parentheses ().
[0-9()]+ matches at least one character that matches the above character class.
^[0-9()]+$ matches strings for which ALL characters match the character class; ^ and $ match the beginning and end of the string, respectively.
In the end, the whole expression is padded on both sides with /, which is the regular expression delimiter. It's short for new RegExp('^[0-9()]+$').
Assuming you are looking for a function to validate your input, considering a validChars parameter:
String.prototype.validate = function (validChars) {
var mychar;
for(var i=0; i < this.length; i++) {
if(validChars.indexOf(this[i]) == -1) { // Loop through all characters of your string.
return false; // Return false if the current character is not found in 'validChars' string.
}
}
return true;
};
var validChars = '0123456789';
var str = $("#textbox1").val().toString();
if (str.validate(validChars)) {
alert("Only valid characters were found! String validates!");
} else {
alert("Invalid Char found! String doesn't validate.");
}
However, This is quite a load of code for a string validation. I'd recommend looking into regexes, instead. (Jack's got a nice answer up here)
You are passing the entire list of validChars to indexOf(). You need to loop through the characters and check them one-by-one.
Demo
String.prototype.Contains = function (str) {
var mychar;
for(var i=0; i<str.length; i++)
{
mychar = this.substr(i, 1);
if(str.indexOf(mychar) == -1)
{
return false;
}
}
return this.length > 0;
};
To use this on integers, you can convert the integer to a string with String(), like this:
var myint = 33; // define integer
var strTest = String(myint); // convert to string
console.log(strTest.Contains("0123456789")); // validate against chars
I'm only guessing, but it looks like you are trying to check a phone number. One of the simple ways to change your function is to check string value with RegExp.
String.prototype.Contains = function(str) {
var reg = new RegExp("^[" + str +"]+$");
return reg.test(this);
};
But it does not check the sequence of symbols in string.
Checking phone number is more complicated, so RegExp is a good way to do this (even if you do not like it). It can look like:
String.prototype.ContainsPhone = function() {
var reg = new RegExp("^\\([0-9]{3}\\)[0-9]{3}-[0-9]{2}-[0-9]{2}$");
return reg.test(this);
};
This variant will check phones like "(123)456-78-90". It not only checks for a list of characters, but also checks their sequence in string.
Thank you all for your answers! Looks like I'll use regular expressions. I've tried all those solutions but really wanted to be able to pass in a string of validChars but instead I'll pass in a regex..
This works for words, letters, but not integers. I wanted to know why it doesn't work for integers. I wanted to be able to mimic the FilteredTextBoxExtender from the ajax control toolkit in MVC by using a custom Attribute on a textBox
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