Introduction

Just how common it is to use strings in programming, is it common to process them. For instance one may want to find the number of character in a string, or slice a part of it, replace certain occurrences in it from a given substring, convert the string to uppercase characters and much more.

JavaScript provides developers with a solid handful of string methods to aid in processing strings for different purposes. In this chapter we will go over some of the most useful of these and how exactly to use them. We'll solve common problems using the methods and test your skills by assigning you various tasks in the way.

So why are we waiting here?

Changing casing

JavaScript provides with two string methods to change the casing of characters to either all lowercase, or all uppercase.

They are toLowerCase() and toUpperCase(), respectively.

string.toLowerCase()
string.toUpperCase()

Both require no arguments at all — just call them and let the casing be changed.

Consider the snippet below:

'Hello World!'.toLowerCase()
'hello world'
'Hello World!'.toUpperCase()
'HELLO WORLD!'

In the first statement, we get the lowercased version of the string 'Hello World!' returned which is 'hello world!', while in the second one, we get the uppercased version returned, which is 'HELLO WORLD!'.

It's quite common to use toLowerCase() or toUpperCase() on strings when comparing them.

For instance, when comparing two strings together for equality, where the casing of characters doesn't matter, we would first convert both of them to lowercase (or uppercase) and then perform the comparison.

An example follows:

var s = 'JavaScript';
var lang = prompt();

if (lang.toLowerCase() === s.toLowerCase()) {
   console.log('You know JavaScript');
}

Here we create a string s and then a variable lang which is assigned the return value of a prompt dialog. In this prompt, the user could enter the text 'JavaScript' in any casing, like 'JavaSCRIPT', 'JAVASCRIPT' etc.

Our program converts both this return value and the string s into lowercase before comparing them, to make sure that all matching input values (with potentially different casing) lead to the desired console log.

Trimming whitespace characters

Oftem times while working with user input, you'll come across strings with redundant pieces of whitespace characters in the beginning or end.

Whitespace characters include spaces, tabs (\t), carriage returns (\r) and newlines (\n).

For instance, a user might have input a value containing extra spaces in the beginning or there might be unnecessary newlines at the end.

To clear away such characters from the string, we could use the trim() method.

The trim() method removes whitespace characters from both ends of a given string.

Here's its syntax:

string.trim()

As with the casing method discussed above, trim() doesn't take any argument — call it as is and let the magic happen!

Shown below are a couple of examples:

'   Hello World!   '.trim()
'Hello World!'
'\n   Hello World!\n\n'.trim()
'Hello World!'

In the first statement, trim() removes all the spaces from both ends of the string. In the second statement, trim() removes all spaces and newline sequences from both ends of the string.

Moving on, in order to remove whitespace characters from only one end of the string, we could use the more specific methods — trimStart() and trimEnd().

Both the methods work exactly like trim(), except for that,

trimStart() operates only on the start of a string and trimEnd() operates only on the end of a string.

Shown below are a couple of examples.

First, let's see trimStart():

'   Hello World!   '.trimStart()
'Hello World! '
'\n   Hello World!\n\n'.trimStart()
'Hello World!\n\n'

And now for trimEnd():

'   Hello World!   '.trimEnd()
' Hello World!'
'\n   Hello World!\n\n'.trimEnd()
'\n Hello World!'

Searching for substrings

There are mainly two methods that could be used to search for given substrings within a main string.

They are indexOf() and lastIndexOf().

The indexOf() method returns the index of the first occurrence of a given substring within a main string. If the substring isn't found, -1 is returned.

Here's the syntax of indexOf():

string.indexOf(substring[, index])

substring is the string to be searched for in string whereas index is the position where to begin the searching. By default, index is set to 0 — the beginning of the string.

If substring is found in string, its index is returned; or otherwise the value -1.

Consider the code below:

var s = 'Hello World!';
console.log(s.indexOf('World'));
6

We search for 'World' in s using indexOf(). What's returned is 6 which is where the substring 'World' begins in s.

Let's consider another example.

var s = 'Hello World!';
console.log(s.indexOf('o'));
4

The second argument is useful when we want to search beyond the first occurrence of a substring.

In the code below we demonstrate this idea:

var s = 'Hello';

var i = s.indexOf('l');
console.log(i);

i = s.indexOf('l', i + 1);
console.log(i);

console.log(s.indexOf('l', i + 1));
2
3
-1

To start with, we retrieve the index of the first occurrence of 'l' in s. This gives us 2 (i.e. the index of the highlighted character in 'Hello World!')

Next, we retrieve the index of the next occurrence of 'l' in s, by giving a second argument to indexOf() which is 1 greater than the index of the last occurrence of 'l'. This gives us 3 (i.e. the index of the highlighted character in 'Hello World!').

After this, once again, we retrieve the index of the next occurrence of 'l' in s beyond the last index i. Since, 'l' doesn't occur anymore, this gives us -1.

Create a function getAllIndexes() that takes in two strings str and substr, and outputs back an array containing the index of each occurrence of substr in str, or otherwise the value -1.

Shown below is an illustration of how should the function work:

getAllIndexes('Hello World!', 'l')
[2, 3, 9]
getAllIndexes('Hello World!', 'd')
[10]
getAllIndexes('Hello World!', 'i')
-1
function getAllIndexes(str, substr) {
   var i = str.indexOf(substr);

   if (i === -1) return -1;

   var indexes = [];
   while (i !== -1) {
      indexes.push(i);
      i = str.indexOf(substr, i + 1);
   }
   return indexes;
}

Splitting strings

A string could be broken down into an array of substrings using the split() method.

The split() method splits a string apart at every occurrence of a given separator, and returns back an array containing the left over substrings.

The syntax is as follows:

string.split([separator[, limit]])

separator specifies the separator at which to break the main string apart. If omitted, split() returns an array containing the whole string. limit specifies the maximum number of elements in the returned array. If omitted, it defaults to 232 - 1.

For instance, let's suppose we want to extract out the numbers from the string '10,20,30'. What we could do is simply call split() on the string specifying the , character as the delimiter.

The method would chop off the string at every occurrence of , and give back the left out segments of substrings in tthe form of an array i.e. the value ['10', '20', '30'].

Shown below are a couple more examples:

'Hello'.split()
["Hello"]
'H e l l o'.split(' ')
["H", "e", "l", "l", "o"]
'H,e,l,l, o'.split(',')
["H", "e", "l", "l", " o"]

If separator is an empty string (''), we get an array of characters returned. This is a common operation in programs that ought to make modifications to certain characters of the string.

'Hello'.split('')
["H", "e", "l", "l", "o"]

Making these modifications directly in the string is challenging as compared to making them in an array where each element is a character. Later on, using the array method join() we could get back the string.

Details to join() to come in the chapter JavaScript Array Methods.

Now let's see how to work with limit.

By default value, it is set to an extremely large value, i.e. 232 - 1, which won't ever be touched in almost all frontend string processing problems.

We could also manually provide an integer value to limit, in which case the array returned would have only that many elements, at max — not more than that.

Shown below are a couple of examples:

'Hello'.split('')
['H', 'e', 'l', 'l', 'o']
'Hello'.split('', 10)
['H', 'e', 'l', 'l', 'o']
'Hello'.split('', 2)
['H', 'e']
'Hello'.split('', 0)
[]

In the first statement, we call split() without a limit argument, and thus get an array of all characters returned. In the second statement, the provided limit is larger than the total number of characters in the string, likewise we get the same array returned as before.

As limit is reached, string splitting is put to a halt and the array created so far returned. This is exactly what happens in the third statement. The remaining segment of the string is not processed at all — we just get the first two characters in the returned array.

In the last statement, limit is 0 and hence we get an empty array returned, with 0 elements.

limit is useful when we want to retrieve only a couple of segments from a string.

Slicing strings

It's a common practice to extract out a small portion of a substring from a given string. This is commonly known as 'slicing' the string.

In JavaScript, there are mainly two methods used for string slicing needs — slice() and substring().

Let's see each one.

slice()

First, exploring slice().

The slice() method slices a string from a starting position to an ending position, and returns back the slice.

Let's see its syntax:

string.slice([start[, end]])

start specifies the index where to begin the slicing. It defaults to 0. end specifies the index where to end the slicing. This is exclusive. It defaults to the length of the string.

Time to see some examples:

'Hello'.slice()
'Hello'
'Hello'.slice(1)
'ello'
'Hello'.slice(1,2)
'e'

Note that the second argument is exclusive i.e. slicing is done upto the index of right before the indexes pointed by end.

The most interesting aspect of slice() is that we could provide it negative arguments as well.

In this case, the index is computed from the end of the string. That is, -1 points to the last character, -2 points to the second last character and so on and so forth.

Consider the following code:

var s = 'Coder';

console.log(s.slice(-2));
console.log(s.slice(-2, -1));
console.log(s.slice(0, -1));
'er"
"r"
"Code'

In the first call to slice(), we retrieve the last two characters of the string s. In the second call, we retrieve the second last character of s. In the third call, we slice the string from the very beginning to the very end, leaving off the last character.

So this is how slice() works. A very similar method is substring().

substring()

Akin to slice(),

The substring() method slices a string from a starting position to an ending position and returns back the slice.

So then what's the difference between slice() and substring()?

The main difference is the way given arguments are perceived in the method's internal implementation.

If the start argument to substring() is greater than end, the arguments are swapped. This doesn't happen with slice().

An illustration follows:

'Hello'.slice(2, 0)
''
'Hello'.substring(2, 0)
'He'

Moreover, if a given argument to substring() is negative, it is taken to be 0 unlike slice() which starts counting from the end of the string.

An illustration follows:

'Hello'.slice(-2, -1)
'l'
'Hello'.substring(-2, -1)
''

In the second statement here, both the negative arguments to substring() get converted to 0, likewise the call substring(-2, -1) translates to substring(0, 0), which simply returns an empty string.

String replacement

The last utility left to be covered in this chapter is that of string replacement. The idea is to replace given substrings in a string with other strings.

The string methods replace() and replaceAll() allow us to perform replacements of given substrings within a string.

replace()

Let's start with replace().

The replace() string method replaces a substring inside a string with a given value.

The syntax of replace() is shown as follows:

string.replace(searchStr, replaceStr)

searchStr is the string to search in string, whereas replaceStr is the string to replace the first occurrence of searchStr in string with.

The replace() method searches for a given substring case-sensitively.

Let's perform a couple of replacements on some strings:

'Hello World!'.replace('World', 'Programmer')
'Hello Programmer!'
'Good'.replace('G', 'F')
'Food'
'Good'.replace('GOOD', 'FOOD')
'Good'
'3 x 3 = 9'.replace('3', '4')
'4 x 3 = 9'

As can be seen in the last statement here, replace() only replaces the first occurrence of a substring inside the main string — in this case, only the first occurrence of '3'.

To replace all occurrences, we could use the replaceAll() method.

replace() and regular expressions

As we shall see later on, even the replace() method could replace all occurrences of a given substring in a main string but only if the first argument is a regular expression with the global (g) flag set.

Regular expressions represent a slightly more advanced, but still not that difficult, area of JavaScript, and programming in general. They are covered from scratch, in detail, in our dedicated JavaScript Regex Course.

Below shown is an example of using a regular expression with replace():

var s = 'Food';
console.log(s.replace(/o/g, 'e'));
Feed

Here, /o/g is the regular expression. Let's quickly understand what it means...

// is how we denote regular expressions literally in JavaScript. In between these, we put a pattern to be matched in a given string. In this case, the pattern is o, which says to match the character 'o' in a given string.

Finally the g at the end of the expression instructs the regular expression engine to search for all occurrences of 'o' in a given string — not just stop at the first one.

This is just the very beginning of regular expressions. We could make extremely complex patterns using them that could match a huge variety of substrings.

You could make yourself able to understand all the complexities of regular expressions in JavaScript by taking our JavaScript Regular Expressions Course.

replaceAll()

The method is similar to replace(), except for one obvious thing.

The replaceAll() method replaces all occurrences of a substring in a string with another value.

Syntactically, it's exactly the same as replace().

string.replaceAll(searchStr, replaceStr)

searchStr is the string to search in string, whereas replaceStr is the string to replace all the occurrences of searchStr in string with.

Consider the snippet below:

'Food'.replaceAll('o', 'e')
'Feed'
'3 x 3 = 9'.replaceAll('3', '4')
'4 x 4 = 9'
'Hello'.replaceAll('a', 'e')
'Hello'

In the last statement, since 'a' doesn't exist in the given string 'Hello', nothing is replaced and the string is returned as is.

In the end

Strings are vital to programming and so are properties and methods to strings. Without the methods, especially, strings can only be written and as-it-is displayed - no functionality and no fun!

Now it may take you sometime to remember the method names i.e where to capitalize, the types of their arguments, how many argument can they can accept, return values etc. That sometime can be a lot of time if you don't practice.

Open the console and start experimenting. Notice the key points discussed in the paragraph above like method names, arguments, etc. Try to relate method functionalities with their names. This way you can ensure a solid grip over JavaScript methods discussed above in no more than just a week.

Remember to be patient and experimental!