How to check whether a string contains a substring in JavaScript?
How to check whether a string contains a substring in JavaScript?
Usually I would expect a String.contains()
method, but there doesn't seem to be one.
String.contains()
What is a reasonable way to check for this?
This question's answers are a collaborative effort: if you see something that can be improved, just edit the answer to improve it! No additional answers can be added here
possible duplicate of JQuery string contains check
– Saswat
Aug 18 '15 at 11:14
you can see speed of
r.indexOf(s) !== -1;
fastest than others. hayageek.com/javascript-string-contains– Sherali Turdiyev
Oct 1 '15 at 5:37
r.indexOf(s) !== -1;
Here a benchmark for the most common ways to check if a string is in a string: jsben.ch/#/o6KmH
– EscapeNetscape
Oct 26 '16 at 9:38
Video covering the best of the options below in < 5 minutes, here: youtube.com/watch?v=KENPi0xTgcE
– ssmith
Dec 14 '16 at 16:19
48 Answers
48
Here is a list of current possibilities:
1. (ES6) includes
—go to answer
includes
var string = "foo",
substring = "oo";
string.includes(substring);
2. ES5 and older indexOf
indexOf
var string = "foo",
substring = "oo";
string.indexOf(substring) !== -1;
String.prototype.indexOf
returns the position of the string in the other string. If not found, it will return -1
.
String.prototype.indexOf
-1
3. search
—go to answer
search
var string = "foo",
expr = /oo/;
string.search(expr);
4. lodash includes—go to answer
var string = "foo",
substring = "oo";
_.includes(string, substring);
5. RegExp—go to answer
var string = "foo",
expr = /oo/; // no quotes here
expr.test(string);
6. Match—go to answer
var string = "foo",
expr = /oo/;
string.match(expr);
Performance tests are showing that indexOf
might be the best choice, if it comes to a point where speed matters.
indexOf
@Steve
indexOf
always returns a number so there’s no need to use !==
. If you want to save bytes, you could use ~'foo'.indexOf('oo')
which returns a truthy value if the substring is found, and a falsy value (0
) if it isn’t.– Mathias Bynens
Jul 7 '11 at 11:00
indexOf
!==
~'foo'.indexOf('oo')
0
For the curious: in two's compliment systems, -1 is represented in binary as all 1s (1111 1111 1111 1111 1111 1111 1111 1111 for 32 bit). The bitwise inverse (~) of this is all zeros, or just zero, and therefore falsy. That's why the squiggle trick works, and it is pretty bad-ass if I must say so myself.
– Adam Tolley
Sep 14 '11 at 21:36
@SebNilsson You forgot to include the
~
operator that I suggested in my comment. ~'hello'.indexOf('h'); // -1, which is truthy
, but ~'hello'.indexOf('x'); // 0, which is falsy
.– Mathias Bynens
Feb 8 '12 at 8:05
~
~'hello'.indexOf('h'); // -1, which is truthy
~'hello'.indexOf('x'); // 0, which is falsy
@pramodc84 that link refers to the
Array
object indexOf
method not to the String
object method– gion_13
Apr 26 '12 at 13:26
Array
indexOf
String
@NicolasBarbulesco I am confident that all of the people who look at my code will know that
[["tn 987654321e-400"]] === 0
is false. I am much less confident that everyone who looks at my code will know that [["tn 987654321e-432"]] == 0
is true.– kybernetikos
Dec 11 '13 at 15:48
[["tn 987654321e-400"]] === 0
[["tn 987654321e-432"]] == 0
You can easily add a contains
method to String with this statement:
contains
String.prototype.contains = function(it) return this.indexOf(it) != -1; ;
Note: see the comments below for a valid argument for not using this. My advice: use your own judgement.
Alternatively:
if (typeof String.prototype.contains === 'undefined') String.prototype.contains = function(it) return this.indexOf(it) != -1; ;
Don't modify objects you don't own. nczonline.net/blog/2010/03/02/…
– zachleat
Feb 17 '11 at 19:59
@zachleat, that understandable in practice. But "foobar".contains("bar") would be a really useful exception to the rule.
– ndbroadbent
Feb 22 '11 at 9:50
Eh, my preference would be to adapt my mental model to fit JavaScript and just use indexOf. It will make the code easier to understand for the next JavaScripter that comes along and has to read it.
– zachleat
Mar 4 '11 at 16:03
if (typeof String.prototype.contains === 'undefined') String.prototype.contains = function(it) return this.indexOf(it) != -1; ;
– Pavel Hodek
Jun 7 '11 at 15:24
if (typeof String.prototype.contains === 'undefined') String.prototype.contains = function(it) return this.indexOf(it) != -1; ;
I this it is preferrable to use this function if you are going to be using this kind of indexOf's frequently. @zachleat, I would disagree that using indexOf is more readable than contains. Contains describes what is happening, where to some
indexOf() != -1
may not be so transparent. But to each their own, as long as you're consistant.– smdrager
Jul 11 '11 at 14:03
indexOf() != -1
The problem with your code is that JavaScript is case sensitive. Your method call
indexof()
should actually be
indexOf()
Try fixing it and see if that helps:
if (test.indexOf("title") !=-1)
alert(elm);
foundLinks++;
@JeremyW, I would say at this point the value of this answer is that people that have made this exact same mistake (
indexof
instead of indexOf
) can find this answer and see what's going on. I wouldn't touch the question any more.– Victor
Nov 18 '14 at 13:23
indexof
indexOf
There is a string.includes
in ES6:
string.includes
"potato".includes("to");
> true
Note you may need to load es6-shim
or similar to get this working on older browsers.
es6-shim
require('es6-shim')
because I was used to "contains" in other languages and just implemented my feature with it, I just ran into the error. So, short feedback about the support. Firefox 19 - OSX => OK, Firefox 19 - Windows => NOK, Chrome - OSX,Windows => NOK
– Patrick Hammer
Feb 21 '13 at 10:18
Like this?
String.prototype.contains = function (segment) return this.indexOf(segment) !== -1; ;
(BTW: Doing things on the prototype is bad)– Nijikokun
May 10 '13 at 2:50
String.prototype.contains = function (segment) return this.indexOf(segment) !== -1; ;
It is not support in chrome.....:(
– Krunal Patel
Jun 24 '14 at 11:15
@Norris It's in ES6. Load ES6 shim. You can use it now.
– mikemaccana
Jan 15 '15 at 14:56
.contains() and .includes() are both experimental, re: non-standard. I would not recommend their use in production systems. I'd stick with .indexOf() for now.
– Mike S.
Mar 22 '15 at 13:47
var index = haystack.indexOf(needle);
You could use the JavaScript search()
method.
search()
Syntax is: string.search(regexp)
string.search(regexp)
It returns the position of the match, or -1 if no match is found.
See examples there: jsref_search
You don't need a complicated regular expression syntax. If you are not familiar with them a simple st.search("title")
will do. If you want your test to be case insensitive, then you should do st.search(/title/i)
.
st.search("title")
st.search(/title/i)
This seems like it would be slower than the indexOf function because it would have to parse the RegEx. However, if you want something case insensitive, your way would be the way to go (I think), although that was not what was asked. Even though it wasn't asked, I'm voting this up just because of the case insensitive option.
– bgw
Jun 3 '10 at 22:21
I haven't run a benchmark, but would
str.toLowerCase().indexOf(searchstr.toLowerCase())
be much more efficient for case-insensitive search?– Tim S.
Jan 31 '12 at 10:29
str.toLowerCase().indexOf(searchstr.toLowerCase())
With a benchmark and it turns out search is more efficient for case insensitive searching. jsperf.com/string-compare-perf-test But it could be tricky to use regex search as you need to escape some characters.
– misaxi
Jul 9 '13 at 6:13
Search can lead to bugs. As misaxi said, you then have to escape some characters. I was using search not realizing that the parameter expected a regex, and was searching for the pipe character. As it turns out, any string .search('|') == 0.
– James Foster
Mar 9 '14 at 10:52
You can use an escapeRegExp function to make the serach text safe.
function escapeRegExp(string)[]/\])/g, "\$1");
from developer.mozilla.org/en/docs/Web/JavaScript/Guide/…– Mark
Jun 5 '14 at 16:23
function escapeRegExp(string)[]/\])/g, "\$1");
String.prototype.includes()
was introduced in ES6.
String.prototype.includes()
Determines whether one string may be found within another string,
returning true or false as appropriate.
var contained = str.includes(searchString [, position]);
searchString
A string to be searched for within this string.
position
The position in this string at which to begin searching for searchString
defaults to 0.
searchString
var str = "To be, or not to be, that is the question.";
console.log(str.includes("To be")); // true
console.log(str.includes("question")); // true
console.log(str.includes("To be", 1)); // false
This may require ES6 shim in older browsers.
FWIW the linked MDN page has a simple shim/polyfill: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
– Salman Abbas
Sep 13 '16 at 19:39
If you were looking for an alternative to write the ugly -1 check, you prepend a ~ tilde instead.
if (~haystack.indexOf('needle')) alert('found');
Joe Zimmerman - you'll see that using ~ on -1 converts it to 0. The number 0 is a
falsey value, meaning that it will evaluate to false when converted to
a Boolean. That might not seem like a big insight at first, but
remember functions like indexOf will return -1 when the query is not
found. This means that instead of writing something similar to this:
if (someStr.indexOf("a") >= 0)
// Found it
else
// Not Found
You can now have fewer characters in your code so you can write it
like this:
if (~someStr.indexOf("a"))
// Found it
else
// Not Found
More details here
Yes, now I would rather recommend polyfill the ES6 standard
includes()
by following this: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…– Christian Landgren
Oct 10 '16 at 9:32
includes()
This piece of code should work well:
var str="This is testing for javascript search !!!";
if(str.search("for") != -1)
//logic
it searches for the passed character or a word if it is found then search returns a integer value which is the position of word in the entire string. If a word or a character is not found then it search function returns -1.
– vaibhav
Jun 1 '12 at 4:43
A common way to write a contains
method in JavaScript is:
contains
if (!String.prototype.contains)
String.prototype.contains = function (arg)
return !!~this.indexOf(arg);
;
The bitwise negation operator (~
) is used to turn -1
into 0
(falsey), and all other values will be non-zero (truthy).
~
-1
0
The double boolean negation operators are used to cast the number into a boolean.
What's the advantage of
!!~
over >-1
?– alex
Dec 12 '12 at 4:29
!!~
>-1
@alex, There isn't any particular advantage other than not relying on magic numbers. Use what you feel comfortable with.
– zzzzBov
Dec 12 '12 at 4:59
@zzzzBov !~~ is just as much relying on the magic number -1, and the fact that its bitwise representation is the complement of 0.
– Martijn
May 14 '13 at 9:33
!!~this.indexOf(arg);
isn't easy understandable and not as clear in the context as it must be. It also relays on the fact ~-1
is 0, agreed with @Martijn. Also it's slower than simple comparison with -1. But clearness is the main factor.– babinik
May 20 '13 at 15:40
!!~this.indexOf(arg);
~-1
@Nick, I never claimed that it was a good way, I just said it was a common way. As far as clarity is concerned, I feel that it's a reasonable way to save a couple bytes for a library, but I tend to use
foo.indexOf('bar') > -1
– zzzzBov
May 20 '13 at 15:43
foo.indexOf('bar') > -1
In ES5
var s = "foo";
alert(s.indexOf("oo") > -1);
In ES6 there are three new methods: includes()
, startsWith()
, endsWith()
.
includes()
startsWith()
endsWith()
var msg = "Hello world!";
console.log(msg.startsWith("Hello")); // true
console.log(msg.endsWith("!")); // true
console.log(msg.includes("o")); // true
console.log(msg.startsWith("o", 4)); // true
console.log(msg.endsWith("o", 8)); // true
console.log(msg.includes("o", 8)); // false
support w3schools.com/jsref/jsref_endswith.asp
– zloctb
Aug 2 '16 at 3:59
Instead of using code snippets found here and there on the web, you can also use a well-tested and documented library. Two Options I would recommend:
1st option: Use Lodash: It has an includes
method:
includes
_.includes('foobar', 'ob');
// → true
Lodash is the most popular javascript library dependency for npm and has loads of handy javascript utility methods. So for many projects you would want this anyway ;-)
2nd option: Or use Underscore.string: It has an include
method:
include
_.str.include('foobar', 'ob');
// → true
Here is the description of Underscore.string, it just adds 9kb but gives you all the advantages a well-tested and documented library has over copy'n'paste code snippets:
Underscore.string is JavaScript library for comfortable manipulation
with strings, extension for Underscore.js inspired by Prototype.js,
Right.js, Underscore and beautiful Ruby language.
Underscore.string provides you several useful functions: capitalize,
clean, includes, count, escapeHTML, unescapeHTML, insert, splice,
startsWith, endsWith, titleize, trim, truncate and so on.
Note well, Underscore.string is influenced by Underscore.js but can be used without it.
Last not Least: With JavaScript version ES6 comes an built-in includes
method:
includes
'foobar'.includes('ob');
// → true
Most modern browsers already support it, have an eye on the ES6 compatibility table.
I don't see how figuring out the underscore method is in any way superior to simply using the well-documented core functionality provided in javascript, as illustrated here. To the type of coder that copies and pastes code, your sample code would be no more or less a "copy'n'paste code snippet" than any other solution provided here, except, it would require the addition of a library. Adding libraries simply to accomplish tasks that are just as easily done using the native language, regardless of library size, is bad advice. -1 from me for knee-jerk library use on a old question.
– Chris Baker
Jan 12 '14 at 5:37
If you are using Underscore already, you should probably use this approach anyway, as it makes your code more readable and more self-explanatory to people not that familiar with JavaScript... Remember that Stack Overflow answers are useful for more people than just the OP.
– whirlwin
Jan 4 '15 at 22:30
_.str.include seems to be gone in underscore
– pixelearth
Apr 24 '16 at 17:13
@pixelearth It's not in underscore, but underscore.string. The link under
include
in the answer points to the description ;) If you use underscore currently, lodash might be a better solution anyway as it comes with its own includes
method and even more very useful helper functions.– nachtigall
Apr 25 '16 at 12:56
include
includes
You can use jQuery's :contains
selector.
:contains
$("div:contains('John')")
Check it here: contains-selector
That searches DOM elements though…
– sam
Sep 26 '13 at 21:03
dom parsing has nothing to do with the question
– oligofren
Nov 1 '13 at 12:06
it's loosely related... if the string you're searching through happens to be located within a DOM element, jQuery's
:contains
selector can be used.– Joshua Burns
Nov 20 '13 at 20:50
:contains
Use a regular expression:
RegExp.test(string)
RegExp.test(string)
Using a regex is a little overhead to only check for the presence of a substring.
– Fabian Vilers
Nov 24 '09 at 13:55
Benchmarks show otherwise; regex is more efficient in many cases, and more importantly, flexible enough to handle edge cases in a way that other solutions are not.
– Chris Baker
Apr 10 '14 at 21:48
Using regex usually results in 2 problems instead of one.
– martynas
Apr 15 '14 at 8:48
If your string includes . or other regexp literals you will get false positives.
– Christian Landgren
Aug 29 '14 at 10:20
This solutions breaks unless string is regex-escaped.
– Triptych
Oct 12 '15 at 21:22
Another option of doing this is:
You can use the match function, that is, something like:
x = "teststring";
if (x.match("test"))
// Code
match() can also work with regular expression :
x = "teststring";
if (x.match(/test/i))
// Code
if the string "test" includes a . or other regexp literals you will get false positives.
– Christian Landgren
Aug 29 '14 at 10:19
This just worked for me. It selects for strings that do not contain the term "Deleted:"
if (eventString.indexOf("Deleted:") == -1)
You were looking for .indexOf
MDN.
.indexOf
indexOf
is going to return an index to the matched substring. The index will correlate to where the substring starts. If there is no match, a -1 is returned. Here is a simple demo of that concept:
indexOf
var str = "Hello World"; // For example, lets search this string,
var term = "World"; // for the term "World",
var index = str.indexOf(term); // and get its index.
if (index != -1) // If the index is not -1 then the term was matched in the string,
alert(index); // and we can do some work based on that logic. (6 is alerted)
You need to call indexOf with a capital "O" as mentioned. It should also be noted, that in JavaScript class is a reserved word, you need to use className to get this data attribute. The reason it's probably failing is because it's returning a null value. You can do the following to get your class value...
var test = elm.getAttribute("className");
//or
var test = elm.className
Your first approach is not correct: elm.getAttribute("class") == elm.className != elm.getAttribute("className")
– Sebastian vom Meer
Mar 12 '13 at 14:22
Since the question is pretty popular, I thought I could add a little modern flavor to the code.
// const : creates an immutable constant
const allLinks = document.getElementsByTagName("a");
// .reduce.call : gives access to the reduce method on a HTMLCollection
// () => : ES6 arrow function
const foundLinks = .reduce.call(allLinks, (sum, link) => 0);
, 0);
// template literal
console.log(`Found $ title class`);
BTW, the correct answer is misspelling indexOf
or the non-standard String.contains
.
Loading an external library (especially if the code is written in pure JavaScript) or messing with String.prototype
or using a regular expression is a little overkill.
indexOf
String.contains
String.prototype
There is a sleek and better way to do this and it is using the (BitWise NOT) operator.
if(~"John".indexOf("J"))
alert("Found")
else
alert("Not Found");
The Bitwise Not converts "x" into -(x + 1) so, if the x turns out -1 from indexOf method.then it will be converted into -( -1 + 1) = -0 which is a falsy value .
stackoverflow.com/a/23598591/497418 and stackoverflow.com/a/12399125/497418 predate this answer, consider deleting it in favor of the later community wiki answer.
– zzzzBov
May 2 '16 at 20:28
String.prototype.indexOf()
String.prototype.search()
As others have already mentioned, JavaScript strings have both an indexOf
and search
method.
indexOf
search
The key difference between both, is that indexOf
is for plain substrings only, whereas search
also supports regular expressions. Of course, an upside of using indexOf
is that it's faster.
indexOf
search
indexOf
See also In JavaScript, what is the difference between indexOf() and search()?.
String.prototype.contains()
If you want to add your own contains
method to every string, the best way to do it would be @zzzzBov's approach:
contains
if (!String.prototype.contains)
String.prototype.contains = function (arg)
return !!~this.indexOf(arg);
;
You would use it like this:
'Hello World'.contains('orl');
It is generally frowned upon to add your own custom methods to standard objects in JavaScript, for example, because it might break forward compatibility.
If you really want your own contains
method and/or other custom string methods, it's better to create your own utility library and add your custom string methods to that library:
contains
var helper = ;
helper.string =
contains : function (haystack, needle)
return !!~haystack.indexOf(needle);
,
...
;
You would use it like this:
helper.string.contains('Hello World', 'orl');
If you don't want to create your own custom helper library, there is - of course - always the option of using a third-party utility library. As mentioned by @nachtigall, the most popular ones are Lodash and Underscore.js.
In Lodash, you could use _.includes()
, which you use like this:
_.includes()
_.includes('Hello World', 'orl');
In Underscore.js, you could use _.str.include()
, which you use like this :
_.str.include()
_.str.include('Hello World', 'orl');
Simple workaround
if (!String.prototype.contains)
String.prototype.contains= function()
return String.prototype.indexOf.apply(this, arguments) !== -1;
;
you can use in the following way
"hello".contains("he") // true
"hello world".contains("lo w")//true
"hello world".contains("lo wa")//false
"hello world".contains(" ")//true
"hello world".contains(" ")//false
MDN reference
Don’t modify objects you don’t own.
– Michał Perłakowski
Dec 11 '15 at 18:25
Example
var a = "Test String";
if(a.search("ring")!=-1)
//exist
else
//not found
ES6 contains String.prototype.includes
.
String.prototype.includes
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
@MikeMüller The question was why there is not a
String.contains
method, and the answer is that there is one in ES6. The link is provided merely as additional documentation.– user663031
Jan 4 '16 at 5:35
String.contains
There was a contains in pre-release ES6 but it was changed to includes. Your contains method link redirects to the includes method here: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Here's the proof it was renamed: bugzilla.mozilla.org/show_bug.cgi?id=1102219
– Jeremy Odekirk
Jun 2 '16 at 19:08
JavaScript code to use the contains
method in an array:
contains
<html>
<head>
<h2>Use of contains() method</h2>
<script>
Array.prototype.contains = function (element)
for (var i = 0; i < this.length; i++)
if (this[i] == element)
return true;
return false;
arr1 = ["Rose", "India", "Technologies"];
document.write("The condition is "+arr1.contains("India")+"<br>");
</script>
</head>
<b>[If the specified element is present in the array, it returns true otherwise
returns false.]</b>
</html>
In the given code the contains
method determines whether the specified element is present in the array or not. If the specified element is present in the array, it returns true, otherwise it returns false.
contains
-1; this question is about strings, not arrays.
– Mark Amery
Apr 20 '14 at 16:49
a string is an array of chars :)
– daslicht
Apr 22 '14 at 8:51
The sample HTML is not well formed - the
body
tag is missing.– Peter Mortensen
Oct 26 '14 at 10:22
body
To collect some kind of valid solutions:
var stringVariable = "some text";
var findString = "text";
//using `indexOf()`
var containResult1 = stringVariable.indexOf(findString) != -1;
document.write(containResult1+', ');
//using `lastIndexOf()`
var containResult2 = stringVariable.lastIndexOf(findString) != -1;
document.write(containResult2+', ');
//using `search()`
var containResult3 = stringVariable.search(findString) != -1;
document.write(containResult3+', ');
//using `split()`
var containResult4 = stringVariable.split(findString)[0] != stringVariable;
document.write(containResult4+'');
I don't see any point in using
lastIndexOf
if you only want to check if a string contains a substring. search
method is only for regular expressions. split
method makes it only more complicated.– Michał Perłakowski
Dec 11 '15 at 18:29
lastIndexOf
search
split
Since there is a complaint about using the prototype, and since using indexOf
makes your code less readable, and since regexp is overkill:
indexOf
function stringContains(inputString, stringToFind)
return (inputString.indexOf(stringToFind) != -1);
That is the compromise I ended up going for.
JavaScript
var str = "My big string contain apples and oranges";
var n = str.indexOf("apples");
alert(n); //will alert 22, -1 if not found
jQuery
<p>My big string contain apples and oranges</p>
alert($("p:contains(apples)")[0] != undefined); //will alert true if found
Use the inbuilt and simplest one i.e match()
on the string. To achieve what you are looking forward do this:
match()
var stringData ="anyString Data";
var subStringToSearch = "any";
// This will give back the substring if matches and if not returns null
var doesContains = stringData.match(subStringToSearch);
if(doesContains !=null)
alert("Contains Substring");
The easyest way is indeed using indexOf. To just check a string string
for a substring substr
you can use this method:
string
substr
string = "asdf";
substr = "as";
alert(string.indexOf(substr) == -1 ? false : true);
As you wanted the function string.contains()
, you can implement it yourself like this:
string.contains()
String.prototype.contains = function(test)
return this.indexOf(test) == -1 ? false : true;
;
Now you can use this ecen shorter method to check if a string contains a special substring:
string = "asdf";
alert(string.contains("as"));
Here is a JSFiddle as well.
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
It's easy with the indexOf method, you can see a tutorial of indexOf and substring here: dreamsyssoft.com/javascript-shell-scripting/…
– Triton Man
Mar 30 '15 at 17:53