Mastering JavaScript Strings And Regular Expressions
Tags: javascript, webdev, programming
Published: 2021-01-03 11:16:22

Good day guys, first thing first, i would like to congratulate you for making it to 2021, phew! 2020 was like all the things i dint wish for, if 2020 was a great year for you then i really do envy you. I just wanna wish every one a prosperous 2021.

In this article i will be discussing about strings in JavaScript and how you can manipulate them to achieve some complex task through with some simple string methods and by the time you are done with this article you will feel more comfortable working with strings in JavaScript. This article is a series of articles and we will also look up regular expressions too because they make working with strings easier and fun. Strings are often not taken seriously by most programmers but i bet you, knowing how to work with string very well will save you having to download an unnecessary library to do some simple task, Or headaches when you want parse a string into an object. By the end of this article on strings you will be able to write a function that parses a URL into an object. Let's dive in.

## What are Strings
Strings are a data type that are used to hold letters, symbols, numbers and other characters. Basically a string data type only holds characters however numbers, letters, and other symbols are characters so they can be used in the string data type. A string can hold one or more characters hence the name string (it is actually character string). To specify a string in JavaScript, you declare a variable and you set the variable to be equal to the following characters you'd would like the string to contain surrounded by either single quotes or double quotes like;

```javascript
let myString = 'foo'
// THIS IS A STRING

let bar = "bar"
// THIS IS ALSO A STRING
console.log(myString, bar)
// prints out foo, bar
```

A sting can hold a letter, a word or a sentence as far as it is surrounded by double or single quotes, it is treated like just one string;

```javascript
let myString = 'welcome to 2021'
// we have a sencetence and that's fine
console.log(myString)
// logs out welcome to 2021
```

You can also enclose a string with back ticks and that's okay too, back ticks were introduced in ES6 to allow for easy interpolation of variables, but that is a discussion for another day. Don't mix up double quotes and single quotes on one string or it will result in an error, if you absolutely have to make sure you escape the it using a backslash.

```javascript
let quotedString = 'I\'m coming'
console.log(quotedString)
//prints out I'm coming
```

## JavaScript String Methods
Let's take a look at some string methods

### concat
The concat method allows you join two strings together. The string that we are concatenating to the first one will be added at the end of it.

```javascript
let hero = 'super'
console.log(hero.concat('man'))
// prints out superman
```
this can be achieved by also using the + operator, if one side of the argument supplied to this operator is a string, then it takes the two values and concatenates(adds) the string to the none-string or string variable and the result is a string, see what I mean;

```javascript
let hero = 'thor'
console.log(hero + 1, 1 + hero);
// prints out thor1, 1thor
```
### array like methods
It is to note that a string is an array like structure, yes a string is just an array of characters however it doesn't support of the box array methods like find, forEach, filter e.tc but we can find the length of a string, get the index of a particular character, loop through the string, and even make an array from the characters of the string, let's see some example

```javascript
let hero = 'batman'
console.log(batman.length)
// prints out 6
```
The length of a string is the total number of characters in the string and in our above example we get 6, let's try getting the index of a particular character

```javascript
let hero = 'logan'
console.log(hero.indexOf('a'))
// prints out 3
```
IndexOf will return the index of the first match from left to right if there is more than one occurrence of that character or word in the string. Very much like how we get the index of an item from a array. You could try to loop through the array, we can also use slice() on a string too.

```javascript
let hero = 'wolverine'
console.log(hero.slice(0,1))
// prints out w
```
We can combine this methods to achive some great results;

```javascript
let myHero = 'hero=hulk'
let obj = {}
let k = myHero.slice(0, myHero.indexOf('='))
let v = myHero.slice(myHero.indexOf('=') + 1, myHero.length)
obj[k] = v
console.log(obj)

// prints out 
{ hero : 'hulk'}
```
We just parsed a string into an object! since we are sure that our string will contain an equal to somewhere, what we did is we set a variable k equal to the first character in the string up till we get to the = and then we stop. Then we created another variable v and set it equal to the first character after the equal to uptill we get to the end of the string using the length property of the string. We achieved this using the simple methods discussed above, however we now have an object. We can group this into a resuable function if we want.

We can also convert the string to an array
```javascript
let hero = 'wolverine'
console.log(hero.split(''))
// prints out ['w', 'o', 'l', 'v', 'e', 'r', 'i', 'n', 'e']
```

if we have more than one word inside the string we pass it a delimiter that tells the split function how to find each individual item in the string to be separated into the array.

```javascript
let justiceLeague = 'superman batman wonderwoman MMH cyborg aquaman'
let heroArray = justiceLeague.split(' ')
console.log(heroArray)
// prints out [ 'superman', 'batman', 'wonderwoman', 'MMH', 'cyborg', 'aquaman' ]
```
In the above example our delimiter is just an empty space because the different heroes are separated by spaces, if we used a comma in the string to separate the heores then we would pass a comma to the split function. 

### case conversion
We can convert a string from one case to another case, say we are storing users email in a database and it's best to do that when the email is lowercase. We can't trust our users to type their email in lowercase so we can do this;

```javascript
let userEmail = "SuperMan@google.com" //or get email somehow
userEmail = userEmail.toLowerCase
console.log(userEmail)
// prints out superman@google.com
```
we could also use the reverse of this and make the string all uppercase using toUpperCase() method

```javascript
let villian = 'thanos'
console.log(villian.toUpperCase())
// prints out THANOS
```
### character & character code
We could get the character at an index in a given string, that is to say that if we want to know the particular character at a position in a string we could use the charAt() to do so. we can go one step further and get the character code at an index instead of a particular character

```javascript
let hero = 'deadpool'
console.log(hero.charAt(4))
// prints out p
console.log(hero.charCodeAt(4))
// prints out 112 - character encoding for p
```

You could also convert a character encoding to a string using the fromCharCode, this method exists on the global String object, it accepts a number which represents the character encoding of the character

```javascript
let encodedChar = 112
console.log(String.fromCharCode(112, 113))
// prints out pq
```
you can use the spread operator to spread the values of an array that holds char codes into the fromCharCode function


### substring
We can get a fragment of a string if we don't want to use the slice() function, we could use another function called substring(), it accepts 2 parameters which are numbers. The first specifies where to start from while the second specifies where to end. The first character can not be less than 0, and the second cannot be more than the length of the string

```javascript
let heroes = 'antman&hawkeye'
console.log(heroes.substring(0, heroes.indexOf('&')))
// prints out antman
```

### replace
We can replace some part of a string with another string or we can replace the whole string if we want. This is possible using the replace function on the string, it accepts two parameters, the first is a regular expression/word to seach for in the current string. The second argument is the string that we want to replace the match with.

```javascript
let hero = 'superman'
console.log(hero.replace('super', 'spider'))
// prints out spiderman
```

We could use a regular expression but since we have not touched up regular expressions yet, let's allow the sleeping dog lie. We didn't touch up search, match functions because they both accept only regular expressions. When we are dealing with regular expressions we will look at them.

Now i did say we would parse a URL into an object so let's get on with it

```javascript

const parseUrl = function(url){
  // console.log(url)
  let separatedUrl = url.split('//')
  // console.log(separatedUrl)
  let protocol = separatedUrl.find(segment => segment.includes('http'))
  let domainSegment = separatedUrl.find(segment => !segment.includes('http'))
  // console.log(domainSegment)
  domainSegment = domainSegment.split('/')
  // console.log(domainSegment)
  let domain = domainSegment.find(segment => !segment.includes('?'))
  // console.log(domain)
  let queryAndPath = domainSegment.find(segment => segment.includes('?'))
  // console.log(queryAndPath)
  let adressFrag = domain.split(':')
  // console.log(adressFrag)
  let address = adressFrag[0]
  let port = adressFrag.pop()
  // console.log(address, port)
  const splitQueryAndPath = queryAndPath.split('?')
  // console.log(splitQueryAndPath)
  let path = splitQueryAndPath.find(segment => !segment.includes('=&'))
  // console.log(path)
  queryString = splitQueryAndPath.find(segment => segment.includes('&'))
  // console.log(queryString)
  const splitQueryString = queryString.split('&')
  // console.log(splitQueryString);
  const query = {}
  splitQueryString.forEach(string => {
      query[string.slice(0, string.indexOf('='))] = string.slice(string.indexOf('=') +1, string.length)
  })
  // console.log(query)

  return{protocol, domain, address, port, path, query}
}

var url = 'https://localhost:3000/hero?name=thor&weapon=hammer'

const query = parseUrl(url)
console.log(query)
// prints out {
//   protocol: 'https:',
//   domain: 'localhost:3000',
//   address: 'localhost',
//   port: '3000',
//   path: 'hero',
//   query: { name: 'thor', weapon: 'hammer' }
// }
```
### 1
Okay that was a long function, lets break it down first we separate the url that's passed in into a separatedUrl variable using split(), remember this takes a delimeter that determines how the value will be separated. We passed in double foward slahses because a complete url always have double slashes, now we have an array with the protocol and the rest part of the url. We get the protocol using array.find method on the seperatedUrl array to get the item that doesnt have http inisde it.

### 2
We take the second part of the array(separatedUrl) and place the value inside a value called domainSegment, next we split that domainSegment based on a single foward slash and we get another array and store array inside the domainSegment overriding the first value stored in it. and then we repeat the process untill we get to the query string.

### 3
We loop through the array that holds the query string part of the array and for each value of the array we populate the query string object. Each property on the object represents the key of each query param and we set the value of the property to be equal to the value of the query param for that key. Lastly we return an object that has all the extracted value and presents the input query string we gave to it. Try copying it and un-commenting the console logs at each step to get more understanding of how the code works. 

Stay tuned for the next article, I will be focusing on regular expressions and regular expressions are awesome!!