Regular Expressions aka REGEX crash course
Tags: regex, javascript
Published: 2023-03-29 15:00:00

> Also available on my [blog](https://www.nikolasbarwicki.com/articles/regular-expressions-aka-regex-crash-course)

### Regex aka Regular expressions

Regular expressions, also known as "regex", are patterns that help search, match or replace character combinations in strings. They are really powerful and hard to read at the same time. Many developers just decide to skip this part in their learning path and use already prepared regular expressions by googling them or copy/pasting from Stack Overflow.

> You should keep in mind the fact that the syntax of regex differs between different programming languages. Below you can
find examples that will work seamlessly for Javascript - for Python or PHP the syntax might need some adjustments.

## Basics

To find the word `she` in the string `That’s what she said.` you just use the following regular expression: `/she/`.

In Javascript regular expressions are integrated with string methods. To find if a regex matches a string you can you
`.test()` method which returns `true` or `false`.

```javascript
let michaelScott = "That's what she said.";
let regex = /she/;
regex.test(michealScott) // true
```

Let's learn some basics operators:

- to select any character, including special charcters and spaces use period `.`:
```javascript
let str = "abcABC012 .:!?"
let regex = /./g // array of matches: a,b,c,A,B,C,0,1,2, ,.,:,!,?
```

- to select characters at the beginning of a string use caret sign `^`:
```javascript
let str = "abcdef"
let regex1 = /^abc/ // array of matches: a,b,c
let regex2 = /^def/ // no matches
```

- to select characters at the end of a string use dollar sign `$`:
```javascript
let string = "abcdef"
let regex1 = /abc$/ // no matches
let regex2 = /def$/ // array of matches: d,e,f

// you can combine two of those:
let regex1 = /^abc$/
```

- to select at least one defined character add `+`
```javascript
let string = "abc bc aaabc"
let regex = /a+/g // array of matches: a,aaa
```

- to specify how many characters we need we can use quantifiers `{n}`. You can define the exact count: `{2}` or
the range `{2,4)` to match 2-4 times:
```javascript
let string = "12 3456"
let regex1 = /\d{4}/ // array of matches: 3456
let regex2 = /\d{2,4}/g // array of matches: 12,3456
```

## Finding letters, numbers and more
- to select letters `a-z, A-Z`, numbers `0-9` and underscore `_` characters use `\w`. To find charactes other than those
  use `\W`:
```javascript
let string = "abcABC123 _.:!?"
let regex1 = /\w/g // array of matches: a,b,c,A,B,C,1,2,3,_
let regex2 = /\W/g // array of matches:  ,.,:,!,?
```

- to narrow down our search and find only number characters `\d` and everything else except number characters `\D`:
```javascript
let string = "abcABC123 _.:!?"
let regex1 = /\d/g // array of matches: 1,2,3
let regex2 = /\D/g // array of matches: a,b,c,A,B,C, ,_,.,:,!,?
```

- you can also select only space characters with `\s`:
```javascript
let string = "abcABC123 _.:!?"
let regex1 = /\s/g // array of matches: " "
let regex2 = /\S/g // array of matches: a,b,c,A,B,C,1,2,3,_,.,:,!,?
```

- it is also possible to select new line character `\n` or tabulator `\t`

## Character sets and ranges

You can search for any character among given inside square brackets `[...]`.
```javascript
let string = "mop hop top cop"
let regex = /[mtc]op/g // array of matches: mop,top,cop
```
Using caret `^` allows negating defined character set:
```javascript
let string = "mop hop top cop"
let regex = /[^mt]op/g // array of matches: hop,cop
```

By defining the starting and the ending letter you can find the letters in the specified range:
```javascript
let string = "abcdefghijklmnopq"
let regex = /[d-i]/g // array of matches: d,e,f,g,h,i

// and the same with numbers
let string = "0123456789"
let regex = /[2-7]/g // array of matches: 2,3,4,5,6,7
```

> For certain character sets there are corresponding character classes:\
> `\w` is the same as `[a-zA-Z0-9_]`\
> `\d` is the same as `[0-9]`\
> `\s` is almost the same as `[\t\n\v\f\r ]`

## Grouping

We can group a pattern to get a part of the match as a separate item in the result array:
```javascript
let string = "First name: John, Last name: Doe"
let reges = /First name: (\w+), Last name: (\w+)/g
```

Pipe character `|` allows to specify that an expression can be in different expressions. Let's the previous example:
```javascript
let string = "mop hop top cop"
let regex = /(m|t|c)op/g // array of matches: mop,top,cop
```

## Flags
There are 6 flags that affect the search in Javascript's regex but there are only 3 that are used the most:

- `i` - case-insensitive: there's no difference between `Z` and `z`
- `g` - global: with this flag the search returns all possible matches, without this flag only the first match is returned
- `m` - multiline: it affects the behavior of `^` and `$`, in multiline mode the match also at the start or end of line

## Practical examples

### Phone number
```javascript
let regex = /\d{3}(-| )\d{3}(-| )\d{3}/
let phoneNumber1 = "123-123-123" // ✅
let phoneNumber2 = "123 123 123" // ✅
let phoneNumber3 = "123123123" // ❌
let phoneNumber4 = "(123) 123 1234" // ❌
```

### URLs
```javascript
let regex = /^(https?):\/\/[^\s].[^\s]*/
let url1 = "https://www.google.com/" // ✅
let url2 = "http://www.twitter.com/" // ✅
let url3 = "https://nikolasbarwicki.com" // ✅
let url4 = "www.google.com/" // ❌
let url5 = "google.com/" // ❌
```

### Email address
```javascript
let regex = /([a-zA-Z0-9-_.]+)@([a-zA-Z+]).(.+)/
let email1 = "john_10@gmail.com" // ✅
let email2 = "john-doe-10@stanford.edu.com" // ✅
let email3 = "John.Doe@mop.co.uk" // ✅
let email4 = "johndoegmail.com" // ❌
```

## Summary
I truly believe that this article is enough for 90% of all cases when the understanding regular expressions are necessary. 

Thank you so much for reading and happy learning! 🥸