How to do case insensitive string comparison? - javascript
How do I perform case insensitive string comparison in JavaScript?
The simplest way to do it (if you're not worried about special Unicode characters) is to call toUpperCase:
var areEqual = string1.toUpperCase() === string2.toUpperCase();
EDIT: This answer was originally added 9 years ago. Today you should use localeCompare with the sensitivity: 'accent' option:
function ciEquals(a, b) {
return typeof a === 'string' && typeof b === 'string'
? a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0
: a === b;
}
console.log("'a' = 'a'?", ciEquals('a', 'a'));
console.log("'AaA' = 'aAa'?", ciEquals('AaA', 'aAa'));
console.log("'a' = 'á'?", ciEquals('a', 'á'));
console.log("'a' = 'b'?", ciEquals('a', 'b'));
The { sensitivity: 'accent' } tells localeCompare() to treat two variants of the same base letter as the same unless they have different accents (as in the third example) above.
Alternatively, you can use { sensitivity: 'base' }, which treats two characters as equivalent as long as their base character is the same (so A would be treated as equivalent to á).
Note that the third parameter of localeCompare is not supported in IE10 or lower or certain mobile browsers (see the compatibility chart on the page linked above), so if you need to support those browsers, you'll need some kind of fallback:
function ciEqualsInner(a, b) {
return a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0;
}
function ciEquals(a, b) {
if (typeof a !== 'string' || typeof b !== 'string') {
return a === b;
}
// v--- feature detection
return ciEqualsInner('A', 'a')
? ciEqualsInner(a, b)
: /* fallback approach here */;
}
Original answer
The best way to do a case insensitive comparison in JavaScript is to use RegExp match() method with the i flag.
Case-insensitive search
When both strings being compared are variables (not constants), then it's a little more complicated 'cause you need to generate a RegExp from the string but passing the string to RegExp constructor can result in incorrect matches or failed matches if the string has special regex characters in it.
If you care about internationalization don't use toLowerCase() or toUpperCase() as it doesn't provide accurate case-insensitive comparisons in all languages.
http://www.i18nguy.com/unicode/turkish-i18n.html
As said in recent comments, string::localeCompare supports case insensitive comparisons (among other powerful things).
Here's a simple example
'xyz'.localeCompare('XyZ', undefined, { sensitivity: 'base' }); // returns 0
And a generic function you could use
function equalsIgnoringCase(text, other) {
return text.localeCompare(other, undefined, { sensitivity: 'base' }) === 0;
}
Note that instead of undefined you should probably enter the specific locale you are working with. This is important as denoted in the MDN docs
in Swedish, ä and a are separate base letters
Sensitivity options
Browser support
As of time of posting, UC Browser for Android and Opera Mini do not support locale and options parameters. Please check https://caniuse.com/#search=localeCompare for up to date info.
Update:
As per the comments, previous answer checks for source contains keyword, to make it equality check added ^ and $.
(/^keyword$/i).test(source)
With the help of regular expression also we can achieve.
(/keyword/i).test(source)
/i is for ignoring case. If not necessary we can ignore and test for NOT case sensitive matches like
(/keyword/).test(source)
Remember that casing is a locale specific operation. Depending on scenario you may want to take that in to account. For example, if you are comparing names of two people you may want to consider locale but if you are comparing machine generated values such as UUID then you might not. This why I use following function in my utils library (note that type checking is not included for performance reason).
function compareStrings (string1, string2, ignoreCase, useLocale) {
if (ignoreCase) {
if (useLocale) {
string1 = string1.toLocaleLowerCase();
string2 = string2.toLocaleLowerCase();
}
else {
string1 = string1.toLowerCase();
string2 = string2.toLowerCase();
}
}
return string1 === string2;
}
if you are concerned about the direction of the inequality (perhaps you want to sort a list)
you pretty-much have to do case-conversion, and as there are more lowercase characters in unicode than uppercase toLowerCase is probably the best conversion to use.
function my_strcasecmp( a, b )
{
if((a+'').toLowerCase() > (b+'').toLowerCase()) return 1
if((a+'').toLowerCase() < (b+'').toLowerCase()) return -1
return 0
}
Javascript seems to use locale "C" for string comparisons so the resulting ordering will
be ugly if the strings contain other than ASCII letters. there's not much that can be done about that without doing much more detailed inspection of the strings.
I have recently created a micro library that provides case-insensitive string helpers: https://github.com/nickuraltsev/ignore-case. (It uses toUpperCase internally.)
var ignoreCase = require('ignore-case');
ignoreCase.equals('FOO', 'Foo'); // => true
ignoreCase.startsWith('foobar', 'FOO'); // => true
ignoreCase.endsWith('foobar', 'BaR'); // => true
ignoreCase.includes('AbCd', 'c'); // => true
ignoreCase.indexOf('AbCd', 'c'); // => 2
Use RegEx for string match or comparison.
In JavaScript, you can use match() for string comparison,
don't forget to put i in the regular expression. This flag will force case insensitive testing.
Example:
To confirm the string test of any case is included anywhere inside the matchString variable
var matchString = "Test";
if (matchString.match(/test/i)) {
alert('matchString contains the substring "test" case insensitive');
}
else {
alert('matchString does not contain the substring "test" case insensitive');
}
To confirm matchString variable only contains test of any case, and no additional characters, then use zero-width assertions ^ and $ in the regular expression. These will require test to appear directly after the start of the string and directly before the end of the string respecitivly.
var matchString = "Test";
if (matchString.match(/^test$/i)) {
alert('matchString equals "test" case insensitive');
}
else {
alert('matchString does not equal "test" case insensitive');
}
Suppose we want to find the string variable needle in the string variable haystack. There are three gotchas:
Internationalized applications should avoid string.toUpperCase and string.toLowerCase. Use a regular expression which ignores case instead. For example, var needleRegExp = new RegExp(needle, "i"); followed by needleRegExp.test(haystack).
In general, you might not know the value of needle. Be careful that needle does not contain any regular expression special characters. Escape these using needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");.
In other cases, if you want to precisely match needle and haystack, just ignoring case, make sure to add "^" at the start and "$" at the end of your regular expression constructor.
Taking points (1) and (2) into consideration, an example would be:
var haystack = "A. BAIL. Of. Hay.";
var needle = "bail.";
var needleRegExp = new RegExp(needle.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"), "i");
var result = needleRegExp.test(haystack);
if (result) {
// Your code here
}
Lots of answers here, but I like to add a sollution based on extending the String lib:
String.prototype.equalIgnoreCase = function(str)
{
return (str != null
&& typeof str === 'string'
&& this.toUpperCase() === str.toUpperCase());
}
This way you can just use it like you do in Java!
Example:
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
Output will be:
"a == b"
"b != c"
String.prototype.equalIgnoreCase = function(str) {
return (str != null &&
typeof str === 'string' &&
this.toUpperCase() === str.toUpperCase());
}
var a = "hello";
var b = "HeLLo";
var c = "world";
if (a.equalIgnoreCase(b)) {
document.write("a == b");
document.write("<br>");
}
if (a.equalIgnoreCase(c)) {
document.write("a == c");
}
if (!b.equalIgnoreCase(c)) {
document.write("b != c");
}
There are two ways for case insensitive comparison:
Convert strings to upper case and then compare them using the strict operator (===).
Pattern matching using string methods:
Use the "search" string method for case insensitive search.
<!doctype html>
<html>
<head>
<script>
// 1st way
var a = "apple";
var b = "APPLE";
if (a.toUpperCase() === b.toUpperCase()) {
alert("equal");
}
//2nd way
var a = " Null and void";
document.write(a.search(/null/i));
</script>
</head>
</html>
If both strings are of the same known locale, you may want to use Intl.Collator object like this:
function equalIgnoreCase(s1: string, s2: string) {
return new Intl.Collator("en-US", { sensitivity: "base" }).compare(s1, s2) === 0;
}
Obviously, you may want to cache the Collator for better efficiency.
The advantages of this approach is that it should be much faster than using RegExps and is based on an extremely customizable (see description of locales and options constructor parameters in the article above) set of ready-to-use collators.
I like this quick shorthand variation -
export const equalsIgnoreCase = (str1, str2) => {
return (!str1 && !str2) || (str1 && str2 && str1.toUpperCase() == str2.toUpperCase())
}
Quick in processing, and does what it is intended to.
I wrote a extension. very trivial
if (typeof String.prototype.isEqual!= 'function') {
String.prototype.isEqual = function (str){
return this.toUpperCase()==str.toUpperCase();
};
}
str = 'Lol', str2 = 'lOl', regex = new RegExp('^' + str + '$', 'i');
if (regex.test(str)) {
console.log("true");
}
Even this question has already been answered. I have a different approach to using RegExp and match to ignore case sensitivity. Please see my link
https://jsfiddle.net/marchdave/7v8bd7dq/27/
$("#btnGuess").click(guessWord);
function guessWord() {
var letter = $("#guessLetter").val();
var word = 'ABC';
var pattern = RegExp(letter, 'gi'); // pattern: /a/gi
var result = word.match(pattern);
alert('Ignore case sensitive:' + result);
}
Convert both to lower string (only once for performance reasons) and compare them with inline ternary operator:
function strcasecmp(s1,s2){
s1=(s1+'').toLowerCase();
s2=(s2+'').toLowerCase();
return s1>s2?1:(s1<s2?-1:0);
}
How about NOT throwing exceptions and NOT using slow regex?
return str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase();
The above snippet assumes you don't want to match if either string is null or undefined.
If you want to match null/undefined, then:
return (str1 == null && str2 == null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
If for some reason you care about undefined vs null:
return (str1 === undefined && str2 === undefined)
|| (str1 === null && str2 === null)
|| (str1 != null && str2 != null
&& typeof str1 === 'string' && typeof str2 === 'string'
&& str1.toUpperCase() === str2.toUpperCase());
Since no answer clearly provided a simple code snippet for using RegExp, here's my attempt:
function compareInsensitive(str1, str2){
return typeof str1 === 'string' &&
typeof str2 === 'string' &&
new RegExp("^" + str1.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + "$", "i").test(str2);
}
It has several advantages:
Verifies parameter type (any non-string parameter, like undefined for example, would crash an expression like str1.toUpperCase()).
Does not suffer from possible internationalization issues.
Escapes the RegExp string.
If you know you're dealing with ascii text then you can just use a uppercase/lowercase character offset comparison.
Just make sure the string your "perfect" string (the one you want to match against) is lowercase:
const CHARS_IN_BETWEEN = 32;
const LAST_UPPERCASE_CHAR = 90; // Z
function strMatchesIgnoreCase(lowercaseMatch, value) {
let i = 0, matches = lowercaseMatch.length === value.length;
while (matches && i < lowercaseMatch.length) {
const a = lowercaseMatch.charCodeAt(i);
const A = a - CHARS_IN_BETWEEN;
const b = value.charCodeAt(i);
const B = b + ((b > LAST_UPPERCASE_CHAR) ? -CHARS_IN_BETWEEN : CHARS_IN_BETWEEN);
matches = a === b // lowerA === b
|| A === b // upperA == b
|| a === B // lowerA == ~b
|| A === B; // upperA == ~b
i++;
}
return matches;
}
For better browser compatibility you can rely on a regular expression. This will work in all web browsers released in the last 20 years:
String.prototype.equalsci = function(s) {
var regexp = RegExp("^"+this.replace(/[.\\+*?\[\^\]$(){}=!<>|:-]/g, "\\$&")+"$", "i");
return regexp.test(s);
}
"PERSON#Ü.EXAMPLE.COM".equalsci("person#ü.example.com")// returns true
This is different from the other answers found here because it takes into account that not all users are using modern web browsers.
Note: If you need to support unusual cases like the Turkish language you will need to use localeCompare because i and I are not the same letter in Turkish.
"I".localeCompare("i", undefined, { sensitivity:"accent"})===0// returns true
"I".localeCompare("i", "tr", { sensitivity:"accent"})===0// returns false
This is an improved version of this answer.
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
Usages & tests:
String.equal = function (s1, s2, ignoreCase, useLocale) {
if (s1 == null || s2 == null)
return false;
if (!ignoreCase) {
if (s1.length !== s2.length)
return false;
return s1 === s2;
}
if (useLocale) {
if (useLocale.length)
return s1.toLocaleLowerCase(useLocale) === s2.toLocaleLowerCase(useLocale)
else
return s1.toLocaleLowerCase() === s2.toLocaleLowerCase()
}
else {
if (s1.length !== s2.length)
return false;
return s1.toLowerCase() === s2.toLowerCase();
}
}
// If you don't mind extending the prototype.
String.prototype.equal = function(string2, ignoreCase, useLocale) {
return String.equal(this.valueOf(), string2, ignoreCase, useLocale);
}
// ------------------ TESTS ----------------------
console.log("Tests...");
console.log('Case sensitive 1');
var result = "Abc123".equal("Abc123");
console.assert(result === true);
console.log('Case sensitive 2');
result = "aBC123".equal("Abc123");
console.assert(result === false);
console.log('Ignore case');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Ignore case + Current locale');
result = "AbC123".equal("aBc123", true);
console.assert(result === true);
console.log('Turkish test 1 (ignore case, en-US)');
result = "IiiI".equal("ıiİI", true, "en-US");
console.assert(result === false);
console.log('Turkish test 2 (ignore case, tr-TR)');
result = "IiiI".equal("ıiİI", true, "tr-TR");
console.assert(result === true);
console.log('Turkish test 3 (case sensitive, tr-TR)');
result = "IiiI".equal("ıiİI", false, "tr-TR");
console.assert(result === false);
console.log('null-test-1');
result = "AAA".equal(null);
console.assert(result === false);
console.log('null-test-2');
result = String.equal(null, "BBB");
console.assert(result === false);
console.log('null-test-3');
result = String.equal(null, null);
console.assert(result === false);
We could also do this using ASCII:
function toLower(a){
let c = "";
for(let i = 0;i<a.length;i++){
let f = a.charCodeAt(i);
if(f < 95){
c += String.fromCharCode(f+32);
}
else{
c += a[i];
}
}
return c;
}
function compareIt(a,b){
return toLower(a)==toLower(b);
}
console.log(compareIt("An ExamPlE" , "an example"));
Related
Boolean conditionals with placeholder [duplicate]
Is there a string.Empty in JavaScript, or is it just a case of checking for ""?
Empty string, undefined, null, ... To check for a truthy value: if (strValue) { // strValue was non-empty string, true, 42, Infinity, [], ... } To check for a falsy value: if (!strValue) { // strValue was empty string, false, 0, null, undefined, ... } Empty string (only!) To check for exactly an empty string, compare for strict equality against "" using the === operator: if (strValue === "") { // strValue was empty string } To check for not an empty string strictly, use the !== operator: if (strValue !== "") { // strValue was not an empty string }
For checking if a variable is falsey or if it has length attribute equal to zero (which for a string, means it is empty), I use: function isEmpty(str) { return (!str || str.length === 0 ); } (Note that strings aren't the only variables with a length attribute, arrays have them as well, for example.) Alternativaly, you can use the (not so) newly optional chaining and arrow functions to simplify: const isEmpty = (str) => (!str?.length); It will check the length, returning undefined in case of a nullish value, without throwing an error. In the case of an empty value, zero is falsy and the result is still valid. For checking if a variable is falsey or if the string only contains whitespace or is empty, I use: function isBlank(str) { return (!str || /^\s*$/.test(str)); } If you want, you can monkey-patch the String prototype like this: String.prototype.isEmpty = function() { // This doesn't work the same way as the isEmpty function used // in the first example, it will return true for strings containing only whitespace return (this.length === 0 || !this.trim()); }; console.log("example".isEmpty()); Note that monkey-patching built-in types are controversial, as it can break code that depends on the existing structure of built-in types, for whatever reason.
All the previous answers are good, but this will be even better. Use dual NOT operators (!!): if (!!str) { // Some code here } Or use type casting: if (Boolean(str)) { // Code here } Both do the same function. Typecast the variable to Boolean, where str is a variable. It returns false for null, undefined, 0, 000, "", false. It returns true for all string values other than the empty string (including strings like "0" and " ")
The closest thing you can get to str.Empty (with the precondition that str is a String) is: if (!str.length) { ...
If you need to make sure that the string is not just a bunch of empty spaces (I'm assuming this is for form validation) you need to do a replace on the spaces. if(str.replace(/\s/g,"") == ""){ }
I use: function empty(e) { switch (e) { case "": case 0: case "0": case null: case false: case undefined: return true; default: return false; } } empty(null) // true empty(0) // true empty(7) // false empty("") // true empty((function() { return "" })) // false
Performance I perform tests on macOS v10.13.6 (High Sierra) for 18 chosen solutions. Solutions works slightly different (for corner-case input data) which was presented in the snippet below. Conclusions the simple solutions based on !str,==,=== and length are fast for all browsers (A,B,C,G,I,J) the solutions based on the regular expression (test,replace) and charAt are slowest for all browsers (H,L,M,P) the solutions marked as fastest was fastest only for one test run - but in many runs it changes inside 'fast' solutions group Details In the below snippet I compare results of chosen 18 methods by use different input parameters "" "a" " "- empty string, string with letter and string with space [] {} f- array, object and function 0 1 NaN Infinity - numbers true false - Boolean null undefined Not all tested methods support all input cases. function A(str) { let r=1; if (!str) r=0; return r; } function B(str) { let r=1; if (str == "") r=0; return r; } function C(str) { let r=1; if (str === "") r=0; return r; } function D(str) { let r=1; if(!str || 0 === str.length) r=0; return r; } function E(str) { let r=1; if(!str || /^\s*$/.test(str)) r=0; return r; } function F(str) { let r=1; if(!Boolean(str)) r=0; return r; } function G(str) { let r=1; if(! ((typeof str != 'undefined') && str) ) r=0; return r; } function H(str) { let r=1; if(!/\S/.test(str)) r=0; return r; } function I(str) { let r=1; if (!str.length) r=0; return r; } function J(str) { let r=1; if(str.length <= 0) r=0; return r; } function K(str) { let r=1; if(str.length === 0 || !str.trim()) r=0; return r; } function L(str) { let r=1; if ( str.replace(/\s/g,"") == "") r=0; return r; } function M(str) { let r=1; if((/^\s*$/).test(str)) r=0; return r; } function N(str) { let r=1; if(!str || !str.trim().length) r=0; return r; } function O(str) { let r=1; if(!str || !str.trim()) r=0; return r; } function P(str) { let r=1; if(!str.charAt(0)) r=0; return r; } function Q(str) { let r=1; if(!str || (str.trim()=='')) r=0; return r; } function R(str) { let r=1; if (typeof str == 'undefined' || !str || str.length === 0 || str === "" || !/[^\s]/.test(str) || /^\s*$/.test(str) || str.replace(/\s/g,"") === "") r=0; return r; } // --- TEST --- console.log( ' "" "a" " " [] {} 0 1 NaN Infinity f true false null undefined '); let log1 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")} ${f([])} ${f({})} ${f(0)} ${f(1)} ${f(NaN)} ${f(Infinity)} ${f(f)} ${f(true)} ${f(false)} ${f(null)} ${f(undefined)}`); let log2 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")} ${f([])} ${f({})} ${f(0)} ${f(1)} ${f(NaN)} ${f(Infinity)} ${f(f)} ${f(true)} ${f(false)}`); let log3 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")}`); log1('A', A); log1('B', B); log1('C', C); log1('D', D); log1('E', E); log1('F', F); log1('G', G); log1('H', H); log2('I', I); log2('J', J); log3('K', K); log3('L', L); log3('M', M); log3('N', N); log3('O', O); log3('P', P); log3('Q', Q); log3('R', R); And then for all methods I perform speed test case str = "" for browsers Chrome v78.0.0, Safari v13.0.4, and Firefox v71.0.0 - you can run tests on your machine here
You can use lodash: _.isEmpty(value). It covers a lot of cases like {}, '', null, undefined, etc. But it always returns true for Number type of JavaScript primitive data types like _.isEmpty(10) or _.isEmpty(Number.MAX_VALUE) both returns true.
Very generic "All-In-One" Function (not recommended though): function is_empty(x) { return ( //don't put newline after return (typeof x == 'undefined') || (x == null) || (x == false) //same as: !x || (x.length == 0) || (x == 0) // note this line, you might not need this. || (x == "") || (x.replace(/\s/g,"") == "") || (!/[^\s]/.test(x)) || (/^\s*$/.test(x)) ); } However, I don't recommend to use that, because your target variable should be of specific type (i.e. string, or numeric, or object?), so apply the checks that are relative to that variable.
var s; // undefined var s = ""; // "" s.length // 0 There's nothing representing an empty string in JavaScript. Do a check against either length (if you know that the var will always be a string) or against ""
Try: if (str && str.trim().length) { //... }
I would not worry too much about the most efficient method. Use what is most clear to your intention. For me that's usually strVar == "". As per the comment from Constantin, if strVar could some how end up containing an integer 0 value, then that would indeed be one of those intention-clarifying situations.
A lot of answers, and a lot of different possibilities! Without a doubt for quick and simple implementation the winner is: if (!str.length) {...} However, as many other examples are available. The best functional method to go about this, I would suggest: function empty(str) { if (typeof str == 'undefined' || !str || str.length === 0 || str === "" || !/[^\s]/.test(str) || /^\s*$/.test(str) || str.replace(/\s/g,"") === "") return true; else return false; } A bit excessive, I know.
check that var a; exist trim out the false spaces in the value, then test for emptiness if ((a)&&(a.trim()!='')) { // if variable a is not empty do this }
You could also go with regular expressions: if((/^\s*$/).test(str)) { } Checks for strings that are either empty or filled with whitespace.
I usually use something like this, if (!str.length) { // Do something }
Also, in case you consider a whitespace filled string as "empty". You can test it with this regular expression: !/\S/.test(string); // Returns true if blank.
If one needs to detect not only empty but also blank strings, I'll add to Goral's answer: function isEmpty(s){ return !s.length; } function isBlank(s){ return isEmpty(s.trim()); }
if ((str?.trim()?.length || 0) > 0) { // str must not be any of: // undefined // null // "" // " " or just whitespace } Or in function form: const isNotNilOrWhitespace = input => (input?.trim()?.length || 0) > 0; const isNilOrWhitespace = input => (input?.trim()?.length || 0) === 0;
Starting with: return (!value || value == undefined || value == "" || value.length == 0); Looking at the last condition, if value == "", its length must be 0. Therefore drop it: return (!value || value == undefined || value == ""); But wait! In JavaScript, an empty string is false. Therefore, drop value == "": return (!value || value == undefined); And !undefined is true, so that check isn't needed. So we have: return (!value); And we don't need parentheses: return !value
I use a combination, and the fastest checks are first. function isBlank(pString) { if (!pString) { return true; } // Checks for a non-white space character // which I think [citation needed] is faster // than removing all the whitespace and checking // against an empty string return !/[^\s]+/.test(pString); }
I have not noticed an answer that takes into account the possibility of null characters in a string. For example, if we have a null character string: var y = "\0"; // an empty string, but has a null character (y === "") // false, testing against an empty string does not work (y.length === 0) // false (y) // true, this is also not expected (y.match(/^[\s]*$/)) // false, again not wanted To test its nullness one could do something like this: String.prototype.isNull = function(){ return Boolean(this.match(/^[\0]*$/)); } ... "\0".isNull() // true It works on a null string, and on an empty string and it is accessible for all strings. In addition, it could be expanded to contain other JavaScript empty or whitespace characters (i.e. nonbreaking space, byte order mark, line/paragraph separator, etc.).
Meanwhile we can have one function that checks for all 'empties' like null, undefined, '', ' ', {}, []. So I just wrote this. var isEmpty = function(data) { if(typeof(data) === 'object'){ if(JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]'){ return true; }else if(!data){ return true; } return false; }else if(typeof(data) === 'string'){ if(!data.trim()){ return true; } return false; }else if(typeof(data) === 'undefined'){ return true; }else{ return false; } } Use cases and results. console.log(isEmpty()); // true console.log(isEmpty(null)); // true console.log(isEmpty('')); // true console.log(isEmpty(' ')); // true console.log(isEmpty(undefined)); // true console.log(isEmpty({})); // true console.log(isEmpty([])); // true console.log(isEmpty(0)); // false console.log(isEmpty('Hey')); // false
I did some research on what happens if you pass a non-string and non-empty/null value to a tester function. As many know, (0 == "") is true in JavaScript, but since 0 is a value and not empty or null, you may want to test for it. The following two functions return true only for undefined, null, empty/whitespace values and false for everything else, such as numbers, Boolean, objects, expressions, etc. function IsNullOrEmpty(value) { return (value == null || value === ""); } function IsNullOrWhiteSpace(value) { return (value == null || !/\S/.test(value)); } More complicated examples exists, but these are simple and give consistent results. There is no need to test for undefined, since it's included in (value == null) check. You may also mimic C# behaviour by adding them to String like this: String.IsNullOrEmpty = function (value) { ... } You do not want to put it in Strings prototype, because if the instance of the String-class is null, it will error: String.prototype.IsNullOrEmpty = function (value) { ... } var myvar = null; if (1 == 2) { myvar = "OK"; } // Could be set myvar.IsNullOrEmpty(); // Throws error I tested with the following value array. You can loop it through to test your functions if in doubt. // Helper items var MyClass = function (b) { this.a = "Hello World!"; this.b = b; }; MyClass.prototype.hello = function () { if (this.b == null) { alert(this.a); } else { alert(this.b); } }; var z; var arr = [ // 0: Explanation for printing, 1: actual value ['undefined', undefined], ['(var) z', z], ['null', null], ['empty', ''], ['space', ' '], ['tab', '\t'], ['newline', '\n'], ['carriage return', '\r'], ['"\\r\\n"', '\r\n'], ['"\\n\\r"', '\n\r'], ['" \\t \\n "', ' \t \n '], ['" txt \\t test \\n"', ' txt \t test \n'], ['"txt"', "txt"], ['"undefined"', 'undefined'], ['"null"', 'null'], ['"0"', '0'], ['"1"', '1'], ['"1.5"', '1.5'], ['"1,5"', '1,5'], // Valid number in some locales, not in JavaScript ['comma', ','], ['dot', '.'], ['".5"', '.5'], ['0', 0], ['0.0', 0.0], ['1', 1], ['1.5', 1.5], ['NaN', NaN], ['/\S/', /\S/], ['true', true], ['false', false], ['function, returns true', function () { return true; } ], ['function, returns false', function () { return false; } ], ['function, returns null', function () { return null; } ], ['function, returns string', function () { return "test"; } ], ['function, returns undefined', function () { } ], ['MyClass', MyClass], ['new MyClass', new MyClass()], ['empty object', {}], ['non-empty object', { a: "a", match: "bogus", test: "bogus"}], ['object with toString: string', { a: "a", match: "bogus", test: "bogus", toString: function () { return "test"; } }], ['object with toString: null', { a: "a", match: "bogus", test: "bogus", toString: function () { return null; } }] ];
I didn't see a good answer here (at least not an answer that fits for me) So I decided to answer myself: value === undefined || value === null || value === ""; You need to start checking if it's undefined. Otherwise your method can explode, and then you can check if it equals null or is equal to an empty string. You cannot have !! or only if(value) since if you check 0 it's going to give you a false answer (0 is false). With that said, wrap it up in a method like: public static isEmpty(value: any): boolean { return value === undefined || value === null || value === ""; } PS.: You don't need to check typeof, since it would explode and throw even before it enters the method
Trimming whitespace with the null-coalescing operator: if (!str?.trim()) { // do something... }
There is a lot of useful information here, but in my opinion, one of the most important elements was not addressed. null, undefined, and "" are all falsy. When evaluating for an empty string, it's often because you need to replace it with something else. In which case, you can expect the following behavior. var a = "" var b = null var c = undefined console.log(a || "falsy string provided") // prints ->"falsy string provided" console.log(b || "falsy string provided") // prints ->"falsy string provided" console.log(c || "falsy string provided") // prints ->"falsy string provided" With that in mind, a method or function that can return whether or not a string is "", null, or undefined (an invalid string) versus a valid string is as simple as this: const validStr = (str) => str ? true : false validStr(undefined) // returns false validStr(null) // returns false validStr("") // returns false validStr("My String") // returns true
Try this: export const isEmpty = string => (!string || !string.length);
All these answers are nice. But I cannot be sure that variable is a string, doesn't contain only spaces (this is important for me), and can contain '0' (string). My version: function empty(str){ return !str || !/[^\s]+/.test(str); } empty(null); // true empty(0); // true empty(7); // false empty(""); // true empty("0"); // false empty(" "); // true Sample on jsfiddle.
There's no isEmpty() method, you have to check for the type and the length: if (typeof test === 'string' && test.length === 0){ ... The type check is needed in order to avoid runtime errors when test is undefined or null.
is there a way to check if a string is of this *x.xx.xxxx* format in JavaScript?
I want a function to check if a string is of format x.xx.xxxx in javascript. For example, s.xf.ssfs should return true. And sx.xf.hsdf should return false. Also s.fsd.sfdf should return false.
Here's a reducer version const isValid = s => s.split('.').reduce((b,a,i) => a.length === [1,2,4][i] ? b+1 : b, 0) === 3 console.log(isValid('s.xf.ssfs')); console.log(isValid('ds.xf.ssfs')); console.log(isValid('5.32.9850'))
For a non-regex, for loop option: const test1 = 's.xf.ssfs'; const test2 = 'sx.xf.hsdf'; function correctFormat(str) { if (str.length !== 9) { return false; } if (str[1] !== '.' || str[4] !== '.') { return false; } for (let i = 0; i < 9; i++) { if (i !== 1 && i !== 4 && str[i] === '.') { return false; } } return true; } console.log(correctFormat(test1)); console.log(correctFormat(test2));
You can try using regex: const regex = new RegExp('[a-z][.][a-z]{2}[.][a-z]{4}'); console.log(regex.test('s.xf.ssfs')); console.log(regex.test('s.fsd.sfdf')); As an alternative you can also split the string by periods and check the length of each individual item: function check(s){ let a = s.split('.'); return a.length == 3 && a[0].length == 1 && a[1].length == 2 && a[2].length == 4; } console.log(check('s.xf.ssfs')); console.log(check('sx.xf.hsdf'));
Regular Expressions are what you are looking for here. Simply define a regex and use the test() method to evaluate a string. For example: const regex = /^[a-z][.][a-z]{2}[.][a-z]{4}$/ console.log(regex.test('s.xf.ssfs')) console.log(regex.test('sx.xf.hsdf')) If you require to accept letters and numbers you could use this regular expression instead to test against: const regex = /^.[.].{2}[.].{4}$/ console.log(regex.test('s.5f.s9fs')) console.log(regex.test('sx.xf.hsdf'))
From a brute force approach you could split the string by . into an array and check the length of the array, and each element within the array as follows: let myArray = myString.split("."); if(myArray.length !== 3){ return false } else if(myArray[0] !== 1 || myArray[1] !== 2 || myArray[3] != 4){ return false } else{return true}
Using regular expression you can achieve it. 1) This example work for letters from "a" to "z" const format = /^[a-z]\.[a-z]{2}\.[a-z]{4}$/; //x.xx.xxxx let test1 = format.test('s.xf.ssfs'); let test2 = format.test('sx.xf.hsdf'); console.log("test1: " + test1); console.log("test2: " + test2); 2) This example work for letters from "a" to "z" and "A" to "Z" const format = /^[a-zA-Z]\.[a-zA-Z]{2}\.[a-zA-Z]{4}$/; //X.Xx.xXXx let test1 = format.test('S.Xf.sSFs'); let test2 = format.test('sx.XF.Hsdf'); console.log("test1: " + test1); console.log("test2: " + test2);
How can I test two strings for equivalence in JavaScript, considering null and empty string the same?
If I compare "a" and "b", that should be false. If I compare "a" and "a", that should be true. If I compare "" and null, that should be true. I could write my own method, but thought there was perhaps a JavaScript shortcut. Edit: I was thinking something like this: areDbSame(s1, s2) { if (s1 === null) s1 = ""; if (s2 === null) s2 = ""; return s1 === s2; } Edit2: Settled on this version: areDbSame(s1, s2) { return (s1 === null ? "" : s1) === (s2 === null ? "" : s2); }
Just before you test the equality of your string, you could do a simple one line enforcement, by converting to '' in the case of null. For example (if you also don't care about undefined, false, etc): // testString becomes the one you are testing var testString = myString || ''; If you only want to ensure null is blank var testString = (myString === null) ? '' : myString; Then you can simply do your string comparisons using testString, and not worry about the null equalities. IMO this is the cleanest answer because it doesn't convolute the original equality testing of javascript strings. It is the same as saying, let's split the problem up into two parts. 1) When should my string be considered blank, and 2) Now I can just check for regular string equality.
function areEqualStrings(a, b) { var otherEqualValues = ['', null]; if(typeof a === 'string' && typeof b === 'string') { return a === b; } else if(otherEqualValues.indexOf(a) > -1 && otherEqualValues.indexOf(b) > -1) { return !a === !b; } else { return false; } } When coercing JavaScript values, !null is true and !'' is true, so those would result in being equal. Here's the test (screenshotted from my console):
This function should do it. It type checks first and short circuits otherwise. function stringCompare(a, b) { if (((a === null || typeof a === 'string') || (b === null || typeof b === 'string')) && ((a === '' && b === null) || (b === '' && a === null) || (a === b))) { return true; } return false; }
No it hasn`t. The two first cases you can do naturally using operator =. The third case it is impossible because "" is considered a empty string and null has any type. So they never can be true naturally. To do this, you have to write your own method. Just to be clear. You can use operators = (equal) to do comparison: == equal to `x == 8 false x == 5 true x == "5" true === equal value and equal type x === 5 true x === "5" false Hope it helps
Determining the case (upper/lower) of the first letter in a string
In a web application, how do I determine whether the first letter in a given string is upper- or lower-case using JavaScript?
You can use toUpperCase: if(yourString.charAt(0) === yourString.charAt(0).toUpperCase()) { //Uppercase! } If you're going to be using this on a regular basis, I would suggest putting it in a function on the String prototype, something like this: String.prototype.isFirstCapital = function() { return this.charAt(0) === this.charAt(0).toUpperCase(); } if(yourString.isFirstCapital()) { //Uppercase! } Update (based on comments) I don't know what you actually want to do in the case that the string does not being with a letter, but a simple solution would be to add a quick check to see if it does or not, and return false if not: String.prototype.isFirstCapital = function() { return /^[a-z]/i.test(this) && this.charAt(0) === this.charAt(0).toUpperCase(); }
This will work only with English alphabet. var ch = myStr.chatAt(0); if (ch >= 'a' && ch <= 'z') { // small } else if (ch >= 'A' && ch <= 'Z') { // capital } else { // not english alphabet char }
var mystring = "Test string"; var first= ""; if (mystring ) { first= mystring[1]; } if (first) { $('p').each(function() { if ($(this).text().charAt(0).toUpperCase() === $(this).text().charAt(0)) { alert("Uppercase"); } }); }
This will be called recursively until a first letter in a string is approached, otherwise returns 'no letters'. function getFirstCase(string) { if (string === '') return 'no letters'; var firstChar = string.charAt(0); /* * If both lowercase and uppercase * are equal, it is not a letter */ if (firstChar.toLowerCase() === firstChar.toUpperCase()) { return getFirstCase(string.substr(1)); } else { return firstChar.toLowerCase() === firstChar ? 'lowercase' : 'uppercase'; } } Testing: console.log(getFirstCase('alphabet'), getFirstCase('Sunshine'), getFirstCase('123123'), getFirstCase('#Hi'), getFirstCase('\nHAHA'));
I'm surprised no one's offered a regex solution to this - it seems like the easiest by far: function getFirstCase(s) { return (/^[\d\W]*[A-Z]/).test(s) ? 'upper' : (/^[\d\W]*[a-z]/).test(s) ? 'lower' : 'none'; } Blatantly stealing #Lapple's test cases: console.log(getFirstCase('alphabet'), getFirstCase('Sunshine'), getFirstCase('123123'), getFirstCase('#Hi'), getFirstCase('\nHAHA')); // lower upper none upper upper See http://jsfiddle.net/nrabinowitz/a5cQa/
'IsNullOrWhitespace' in JavaScript?
Is there a JavaScript equivalent to .NET's String.IsNullOrWhitespace so that I can check if a textbox on the client-side has any visible text in it? I'd rather do this on the client-side first than post back the textbox value and rely only on server-side validation, even though I will do that as well.
For a succinct modern cross-browser implementation, just do: function isNullOrWhitespace( input ) { return !input || !input.trim(); } Here's the jsFiddle. Notes below. The currently accepted answer can be simplified to: function isNullOrWhitespace( input ) { return (typeof input === 'undefined' || input == null) || input.replace(/\s/g, '').length < 1; } And leveraging falsiness, even further to: function isNullOrWhitespace( input ) { return !input || input.replace(/\s/g, '').length < 1; } trim() is available in all recent browsers, so we can optionally drop the regex: function isNullOrWhitespace( input ) { return !input || input.trim().length < 1; } And add a little more falsiness to the mix, yielding the final (simplified) version: function isNullOrWhitespace( input ) { return !input || !input.trim(); }
It's easy enough to roll your own: function isNullOrWhitespace( input ) { if (typeof input === 'undefined' || input == null) return true; return input.replace(/\s/g, '').length < 1; }
no, but you could write one function isNullOrWhitespace( str ) { // Does the string not contain at least 1 non-whitespace character? return !/\S/.test( str ); }
Try this out Checks the string if undefined, null, not typeof string, empty or space(s /** * Checks the string if undefined, null, not typeof string, empty or space(s) * #param {any} str string to be evaluated * #returns {boolean} the evaluated result */ function isStringNullOrWhiteSpace(str) { return str === undefined || str === null || typeof str !== 'string' || str.match(/^ *$/) !== null; } You can use it like this isStringNullOrWhiteSpace('Your String');
You must write your own: function isNullOrWhitespace(strToCheck) { var whitespaceChars = "\s"; return (strToCheck === null || whitespaceChars.indexOf(strToCheck) != -1); }
trim() is a useful string-function that JS is missing.. Add it: String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g,"") } Then: if (document.form.field.value.trim() == "")
Pulling the relevant parts of the two best answers, you get something like this: function IsNullOrWhitespace(input) { if (typeof input === 'undefined' || input == null) return true; return !/\S/.test(input); // Does it fail to find a non-whitespace character? } The rest of this answer is only for those interested in the performance differences between this answer and Dexter's answer. Both will produce the same results, but this code is slightly faster. On my computer, using a QUnit test over the following code: var count = 100000; var start = performance.now(); var str = "This is a test string."; for (var i = 0; i < count; ++i) { IsNullOrWhitespace(null); IsNullOrWhitespace(str); } var end = performance.now(); var elapsed = end - start; assert.ok(true, "" + count + " runs of IsNullOrWhitespace() took: " + elapsed + " milliseconds."); The results were: RegExp.replace method = 33 - 37 milliseconds RegExp.test method = 11 - 14 milliseconds
You can use the regex /\S/ to test if a field is whitespace, and combine that with a null check. Ex: if(textBoxVal === null || textBoxVal.match(/\S/)){ // field is invalid (empty or spaces) }