# Regular Expressions in JavaScript

Regular Expressions are strings that allow a user to check a series of characters for matches to character combinations in strings.

**Use case example**: to validate a form field by comparing input with regex for a valid email address that verifies conditions such as-
- Must have *@* at certain positions
- Must end in an extension like *.com* / *.org* / *.in*

## Regular Expression syntax

Regular expressions contain 2 forward slashes at start and end, and the pattern used to validate goes in between them. Additionally, flags are added at the end after the second forward slash if needed, to modify the matching behavior
```
let regex = /pattern/flags
```

In JavaScript, regular expressions are objects. JavaScript provides the built-in `RegExp` type that allows you to work with regular expressions effectively.
```
let regex = new RegExp("pattern", "flags");
```

- **pattern** : The text of the regular expression.

- **flags**: If specified, it is a string that contains the flags to be added.


## Creating a Regular Expression
```
let regex = /rohan/;
```

> Note that a regular expression doesn’t have single quotes or double quotes like a regular string.

The `RegExp` constructor can also be used for the same:
```
let regex = new RegExp('rohan');
```
Both regular expressions are the instances of the `RegExp` type. They match the string 'rohan'.

## Testing for matching
The `RegExp` object has many useful methods. One of them is the `test()` method that allows users to test if a string contains a match of the pattern specified in the regular expression.<BR>
 It executes a search for a match between:
- a regular expression and
- a specified string

The `test()` method returns true or false depending on whether the string argument contains a match.

The following example shows how to use the test() method:
```
let regex = /hello/;
let result = regex.test("hello Rohan");

console.log(result); // true
```

## Using pattern flags
Besides a pattern, a `RegExp` object also accepts an optional flag parameter. Flags are settings that change the searching behavior.<br>
Without flags, regex will only match the first occurrence and will be case sensitive.<br>

- **The ignore flag (i)**<br>
The ignore or `i` flag ignores case when searching.<br>
By default, searches are case-sensitive. For example /hello/ only matches the string hello not Hello, or HELLO.<br>
To search for a string irrespective of  case, utilize the `i` flag:


-  **The global flag (g)**<br>
Without the global flag `g`, the `RegExp` object only checks for and return the first match from a string, if any.

When the g flag is available, the `RegExp` looks for all matches and returns all of them.

** Note **:  It’s possible to combine flags <br>
eg: `gi` flags combine the ignore `i` and the global `g` flags.



-  **The multiline flag (m)**<br>
 This flag allows the user to perform multiline checks for match with the required pattern.

## Character set

- Character sets allow us to look for a number of characters in a single position. It is specified by mentioning all characters  to be matched  between two square brackets.
```
let regex = /[jr]on/
```
The above regex will match both `jon` and `ron`.

A few examples:

- `/[a-e]/` is the same as `/[abcde]/`

- `/[1-4]/` is the same as `/[1234]/`


- When the number of characters to match become too large, it is more convenient to use the exclude set.
```
let regex = /[^jr]on/
```
The above regex will match all patterns except john and ron.


- We could also use Range to include more characters to match.
```
let regex = /[a-zA-Z]ohan/
``` 
In the above pattern, `[a-zA-Z]` will match any alphabet in the first position.

## Quantifiers
Quantifiers are used to quantify how many times a part of the regular expression should be repeated.  Every time the user wants to repeat something in a regex (for instance, an individual character or a sub-expression)  a quantifier can be written after it to specify how many times it should be repeated.

- **+ Plus** <br>
 A Plus quantifier`+` matches between 1 and any number of times.

- **{ }Curly Brackets**<br>
 A `{ }` quantifier match the character before brackets exactly as many times as mentioned inside the curly brackets.
```
/[a-z]{5,8}/
```
Matches any character between a and z between 5 and 8 times.
```
[a-z]{5,}
```
Matches any character between a and z *atleast*  5 times.


- **. Period**<br>
  A period quantifier ` . ` matches any single character (except newline '\n').

- **^ Caret**<br>
The Caret quantifier `^` is used to check if a string starts with a certain character.

- **$ Dollar**<br>
 The Dollar quantifier `$` is used to check if a string ends with a certain character.

- *** Star**<br>
The Star quantifier `*` matches zero or more occurrences of the pattern left to it.

- **+ Plus** <br>
The Plus quantifier `+` matches one or more occurrences of the pattern left to it.

- **? Question Mark**<br>
 The Question mark quantifier `?` matches zero or one occurrence of the pattern left to it.

- **| Vertical bar**<br>
 Vertical bar quantifier `|` is used for alternation (`OR` operator).
```
let regex = /a|b/
```
Here, a|b match any string that contains either a or b


## Exec() method
The `exec()` method of the `RegExp` performs a search for a match in a string and returns an array that contains detailed information about the match. It returns a result array, or null if it could not find any match.<br>

## Test() method
The `test()` method executes a search for a match between a regular expression and a specified string. Returns `true` if it finds a match, else returns a `false`.

```
let str = "Happy day";
// Look for "Happy"
let regex = /Happy/;
let result = regex.test(str);
``` 

## Searching strings

- The method `value.match(regexp)` returns all matches of regexp in the string `value` as an Array object, and returns *null* if not matches are found.

- The method `value.search(regexp)`returns the position of the match. It returns -1 if the search fails.

For both above methods, the search value (i.e. **regexp**) can be `string` or a `regular expression`.


According to the [docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search)
> When you want to know whether a pattern is found in a string, use `search` (similar to the regular expression `test` method); for more information (but slower execution) use `match` (similar to the regular expression `exec` method).

## Replace() method
`Replace` searches for a match in a string and replaces the matched substring with a replacement substring.

An example is given below
```
let text = "Hey Daniel, good morning";
let result = text.replace('morning,'bye');

console.log(result); // Hey Daniel, good bye
```
In the above example, the `replace()` method  is used to to replace the first occurrence of the string **morning** in the string `text`.

## Summary

- Use `/  /` or `RegExp` constructor to create a regular expression.

- Use the pattern flag e.g., ignore (`i`) / global (`g`) / multiline (`m`) to modify the matching behavior.

- Use the `RegExp.test()` method to determine if a pattern is found in a string.

- Use the `RegExp.exec()` method to find the match and return an array that contains the information of the match.

- Some **string methods** such as `match()` and `replace()` support the regular expressions.


- [Regex101.com](https://regex101.com/) is a good resource to try out regex patterns. It allows us to create regular expressions and check them against inputs to check their validity.



