/^15 Things to Know About Regex$/
Tags: javascript, beginners, webdev
Published: 2021-08-13 18:26:17

Be not afraid! You are about to learn one of the most feared subjects in computer science...

\*dramatic pause\*

**Regex**!

Regex (or regexp) is short for regular expressions and it is a syntax used to describe patterns that are to be matched in texts. For example, one can use regex to identify how many times and where a certain text pattern occurs in a document. 
While at first glance regex may seem daunting, once you know the following 15 things, you will be able to show off to other folks that you know (the basics of) regex!

###1. How to use Regex in JavaScript
Like many other programming languages, JavaScript has commands that allow the use of regex for pattern-matching such as `match()`, `test()`, and `replace()`. Before passing the regex as a parameter or calling a method on it, it must first be defined within two forward slashes (`//`) or through `new RegExp()`:
```js
const regex1 = /bananas/ // define regex 
const regex2 = new RegExp('12') // another way to define regex

const str = "John has 12 bananas" // the string to match the pattern to

// Calling match() returns an array of match(es)
str.match(regex1) // ["bananas"]
str.match(regex2) // ["12"]

// Calling replace() replaces the matched string with the string
// that is provided as the second parameter
str.replace(/12/, '24') // "John has 24 bananas"

// Calling test() returns a boolean based on whether the regex 
// matches the string at least once
/John/.test(str) // true
```

###2. Literals
**Literals** are the simplest form of regex – it is basically the exact text that we want to match:
```js
const str = "foo bar 123!"

str.match(/123!/) // ["123!"]
```

###3. Alternation
**Alternations** are used to match the characters before OR after `|`, the pipe symbol:
```js
const str = "foo bar 123!"

str.match(/hello|bar/) // ["bar"]
```

###4. Character Sets
**Character sets** are used to provide a series of characters within a pair of brackets (`[]`) and allow a match as long as one of those characters are found. Inversely, **negative character sets** allow a match as long as one of those characters are NOT found, and they are denoted by the caret (`^`) symbol before the series of characters:
```js
const str = "bat cat hat"

str.match(/[fgh]at/) // ["hat"]
str.match(/[^bdh]at/) // ["cat"]
```

###5. Wildcards
**Wildcards** are denoted by the period (`.`) and can represent any character (letter, number, symbol, or whitespace). If we want to match an actual period itself, we can include the escape character (`\`) before the period.
```js
const str = "John has 12 bananas."

str.match(/John has .. bananas\./) // ["John has 12 bananas."]
```

###6. Ranges
**Ranges** are a shorthand for providing a sequential range of characters and can be used within character sets. They can be used for both letters and numbers, and they are denoted by the dash character (`-`). Multiple ranges, along with individual characters, can also be provided back-to-back within a character set:
```js
const str = "John has 5 bananas"

str.match(/[0-9]/) // ["5"]
str.match(/[A-Za-z0-9_]/) // ["J"]
```

###7. Shorthand Character Classes
**Shorthand character classes** represent common character ranges such as word characters and digit characters. Inversely, **negated shorthand character classes** match any character that is NOT represented in the character ranges.
```js
const str = "foo bar 123!"

// \w represents any word character AKA [A-Za-z0-9_]
// \W is the negated version
str.match(/\w\w\w/) // ["foo"]
str.match(/\W\W\W/) // ["123"]


// \d represents any digit character AKA [0-9]
// \D is the negated version
str.match(/\d\d\d/) // ["123"]
str.match(/\D\D\D/) // ["foo"]

// \s represents any whitespace character such as spaces or tabs
// \S is the negated version
str.match(/...\s.../) // ["foo bar"]
str.match(/.\S./) // ["foo"]
```

###8. Groupings
**Groupings**, denoted by a pair of parentheses (`()`), are used to group different parts of the regex and separate their logic from each other. These parts or groups are also called capture groups and calling `match()` not only returns the full match but also the captured groups
```js
const str = "foo bar 123!"

str.match(/(foo|bar) .../) // ["foo bar", "foo"]
```

###9. Fixed Quantifiers
**Fixed quantifiers** allow us to indicate the exact number of times a character needs to appear for a match to occur and they are denoted by a pair of curly braces (`{}`) after the character:
```js
const str = "foo bar 123!"

str.match(/\w{3}/) // ["foo"]

// the range of repetitions can be specified by providing 
// a minimum and a maximum. If possible, it matches the 
// highest allowed number of repetitions
str.match(/\w{2,4}/) // ["foo "]
```

###10. Optional Quantifiers
**Optional quantifiers** indicate that the character(s) preceding it can appear either 0 or 1 time, and they are denoted by the question mark (`?`):
```js
const str = "John has 12 apples"

str.match(/John has 12 (red )?apples/) // ["John has 12 apples", undefined]
```

###11. Kleene Star
**Kleene stars**, named after Stephen Cole Kleene who invented regular expressions, indicate that the character(s) preceding it can appear either 0 or more times, and they are denoted by the asterisk mark (`*`):
```js
const str = "cat goes mew"

str.match(/meo*w/) // ["mew"]
```

###12. Kleene Plus
**Kleene plus**, slightly different from Kleene stars, indicate that the character(s) preceding it can appear either ONE or more times, and they are denoted by the plus sign (`+`):
```js
const str = "cow goes moooooooo"

str.match(/mo+/) // ["moooooooo"]
```

###13. Anchors
**Anchors** signify the start and the end of a string, and they are indicated by the hat (`^`) and dollar (`$`) sign, respectively. If anchors are used, patterns won't be matched for texts that are in the middle of a string. New lines (\n) can be used to signify a new "start" of a string: 
```js
const str = "Unhappy cat\nHappy dog"

str.match(/^happy cat$/) // [null]
str.match(/^Happy dog$/) // ["Happy dog"]
```

###14. Lookaheads and Lookbehinds
This is more of an advanced regex concept, but **lookaheads** and **lookbehinds** are zero-length assertions, meaning that they don't actually match characters but they still play a role in deciding whether a match will or will not take place. Lookaheads and lookbehinds specifically look at whether a certain pattern exists before or after the character in question, respectively, to make the decision: 
```js
const str = "foo bar 123!"

// Lookaheads can be positive or negative:
// Positive lookaheads are denoted by (?=) and then a pattern
// after the equal sign. If the previous character is followed by
// the pattern, then the previous character is allowed to match.
// The opposite is true for negative lookaheads, which are denoted
// by (?!):
str.match(/b(?=a)/) // ["b"]
str.match(/b(?!a)/) // [null]

// Lookbehinds can also be positive or negative, and they are
// denoted by (?<=) and (?<!), respectively. As the name implies,
// lookbehinds check whether a pattern appears before the
// character in question:
str.match(/a(?<=b)/) // ["a"]
str.match(/a(?<!b)/) // [null]
```

###15. Flags
Lastly, **flags** are optional modifiers that are included AFTER the regex to describe how the matching will take place:
```js
const str = "foo bar 123!"

// the "g" flag stands for "global matching", which tells the matcher to return all matches, not just one:
str.match(/\w{3}/g) // ["foo", "bar", "123"]

// the "i" flag stands for "case insensitive", which tells the matcher to ignore casing when finding matches:
str.match(/FOO BAR/i) // ["foo bar"]

// the "g" and "i" flags can also be combined:
str.match(/[A-Z]{3}/ig) // ["foo", "bar"]
```

###Conclusion
Woohoo! Now that wasn't so bad, was it?

If you are still struggling to grasp some concepts, I have provided several resources below that definitely helped ME solidify my understanding of regex and get some good practice.

If you are feeling a bit confident, then take a look at the regex used to validate an email address and try to dissect it:
```
(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?: \r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:( ?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\0 31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\ ](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+ (?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?: (?:\r\n)?[ \t])*))*|(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n) ?[ \t])*)*\&lt;(?:(?:\r\n)?[ \t])*(?:@(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\ r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n) ?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t] )*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])* )(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t] )+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*) *:(?:(?:\r\n)?[ \t])*)?(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+ |\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r \n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?: \r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t ]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031 ]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\]( ?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(? :(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(? :\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)|(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(? :(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)? [ \t]))*"(?:(?:\r\n)?[ \t])*)*:(?:(?:\r\n)?[ \t])*(?:(?:(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]| \\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;> @,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|" (?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t] )*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(? :[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[ \]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?:[^()&lt;>@,;:\\".\[\] \000- \031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|( ?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\&lt;(?:(?:\r\n)?[ \t])*(?:@(?:[^()&lt;>@,; :\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([ ^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\" .\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\ ]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\ [\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\ r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\] |\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)?(?:[^()&lt;>@,;:\\".\[\] \0 00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\ .|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@, ;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|"(? :[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*))*@(?:(?:\r\n)?[ \t])* (?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\". \[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t])*(?:[ ^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\] ]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:(?:\r\n)?[ \t])*)(?:,\s*( ?:(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\ ".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:( ?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[ \["()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t ])*))*@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t ])+|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(? :\.(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+| \Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*|(?: [^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\".\[\ ]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)*\&lt;(?:(?:\r\n) ?[ \t])*(?:@(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[" ()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n) ?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;> @,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*(?:,@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@, ;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\.(?:(?:\r\n)?[ \t] )*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\ ".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*)*:(?:(?:\r\n)?[ \t])*)? (?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()&lt;>@,;:\\". \[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t])*)(?:\.(?:(?: \r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[ "()&lt;>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))*"(?:(?:\r\n)?[ \t]) *))*@(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]) +|\Z|(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*)(?:\ .(?:(?:\r\n)?[ \t])*(?:[^()&lt;>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z |(?=[\["()&lt;>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)*\](?:(?:\r\n)?[ \t])*))*\>(?:( ?:\r\n)?[ \t])*))*)?;\s*)
```
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

JUST KIDDING!

There are obviously more things to learn about regex, and even if you know regex to the dot, it won't exactly be a walk in the park to design/decipher complicated regex patterns as shown above.

However, the good news is now you know enough regex to start parsing texts for a variety of useful purposes! That and you can show off to your friends 😎😎😎

Happy coding!

###Resources
- [Intro to Regex - Codecademy](https://www.codecademy.com/learn/introduction-to-regular-expressions)
- [Learn Regex with Simple Exercises](https://regexone.com/)
- [Intro to Regex for Web Developers](https://dev.to/chrisachard/intro-to-regex-for-web-developers-2fj4)
- [Rubular - A Ruby-based Regex Editor](https://rubular.com/)