RegExp Cheatsheet to speed up code editing and refactor
Tags: javascript, vscode, regex, webdev
Published: 2022-01-04 07:30:00

Have you ever asked yourself some of these questions:
- How do I find all the imports of a particular function?
- How do I replace all the variables of the old `Service` implementation with `ServiceLegacy`.
- How do I fix the typo across all the files?
- Which files a particular API endpoint is being used?

If yes, you might find this article a little helpful for your future endeavors.

For some of you, regex might be a mighty beast too difficult to conquer, for a few of the experts out there, my salute to you for mastering the regex magic.

I myself am pretty average in areas of regex, but I know enough to make some of my tasks easy.

I'll start with some regex basics, then move to some common patterns, and then discuss using the newfound regex knowledge (i.e. the topic, speed up code editing).

## A little background
Regex (or sometimes [RegExp](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp) - as in JS), is a sequence of characters that specifies a search pattern.

Perl was one of the modern languages to provide inbuilt support of regex (as Perl was used for text processing, regex support was a necessity), and many of today's tools and languages (including JS and grep) use Perl inspired regex engines.

```
^([A-Za-z0-9_.]+)@([A-Za-z0-9-]+)\.([A-Za-z]{2,15})$
```
<small>[Simple email regex](https://stackoverflow.com/questions/46155/whats-the-best-way-to-validate-an-email-address-in-javascript)</small>

## Regex Basics
| Symbol        | Meaning           |
| ------------- |:-------------:| -----:|
|.|any character except newline |
|*|Match 0 or more characters|
|+|Match 1 or more characters|
|?|Match 0 or 1 characters|
|[abc]|Any of a,b or c|
|[^abc]|not a,b or c|
|[a-z]|Any of a to z|
|^$|Start and end of string|
|\w\d\s|word, digit, whitespace|
|\W\D\S|not word, digit, whitespace|
|a{5}a{2,}|exactly five, two or more|
|a{1,3}|between one & three|

Find the cheatsheet here [Regular Expression Cheatsheet](https://cheatography.com/davechild/cheat-sheets/regular-expressions/pdf/)

### Examples
`.*` Match anything (Will match if the string is empty)
`.+` Match anything (will not match if the string is empty)
`^[a-z]+$` Start and end tokens are there, [a-z]+ will match a string containing characters between a-z and `+` will match if there is at least 1 character. So the expression will match any alphabetical string.

You can learn more here [Regexone](https://regexone.com/)

## Creating Regex
Now let's try making some regex
#### 1. Valid CSS Color
This is simple, should be a hexadecimal string of format RRGGBB.
- `^$` - We don't want any stray ending or starting characters, without this, this will match if any random string contains the hexadecimal string.
- `^[a-f0-9]+$` - match a-f, 0-9, this is now a valid hexadecimal string, but not valid css color
- `^[a-f0-9]{6}$` - exact length of 6
- `^[a-fA-F0-9]{6}$` - case insensitive match

#### 2. Mobile Number
The condition is, should start with +, then 91 (India), then 10 digits.
- `^$` - We want number, and not string containing number.
- `^\+91.*$`, starts with +91, then .* will match anything (`+` is special character, so its escaped with `\`
- `^\+91[0-9]{10}$`, replace `.*` with [0-9]{10} exact 10 occurrences of 0-9 digits.

Let's add another condition, in my country, the number starts with 6,7,8,9, then random 9 digits.
- `^\+91[6789][0-9]{9}$` - This will do it.

I use the [RegExr playground](https://regexr.com/) to test my Regex.

## Find and replace in JS
In JS RegExp, we can have something called capture groups, with which we can group parts of our regex and use them in string manipulation using regex.

A simple example, in the string `aabbcc`, replace all `c` with `a`
```js
// This will replace first occurrence of all `c`s in the string
'aabbcc'.replace(/c*/, 'a');
// OR better
// this will replace all `c`s with a
'aabbcc'.replace(/c/g, 'a');
```
Here `/g` is a modifier for global search in regex. Other modifiers are `/i` (case insensitive search), `/m`, for multiline search.

## VSCode find and replace
Let's say you have a typo in your code, and you named your type as `ButonProps`. And you want to replace it with `ButtonProps`.
Simple Find and replace in VSCode lets you do that.

![VSCode Find and replace](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v6jye2lnso89kj0qbggi.png)
 
Just put the required strings in each input box
![Find and replace typo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mb005ld7jvn24erbpi09.png)
 
### Find Regex in vscode
Now let's say you want to find all the occurrences of `ButtonProps` import. The syntax will look something like this
```ts
import {ButtonProps} from 'Button';
```
But it can be something more complex:
```ts
import Button, {ButtonProps} from 'Button';
//OR
import Button, {ButtonProps, ButtonColor} from 'Button';
```

Now comes our time to use regex in VSCode.
![Regex in VSCode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckdnkwefow6bq6ak66gy.png)
The little button `.*` in the search input box is the regex button toggler.
With regex on, we can now use regex in VSCode search.

So now let's search, and create our regex.
We will first start simple, and then narrow down our search by adding more regex symbols.
Our import statement looks like
```
import something ButtonProps something from button;
```
so our regex will be (replace something with `.*`
`import .*ButtonProps.*from '.*Button';`

![Find ButtonProps](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7di21k50koe9fskanj4b.png)

But there is some noise, we are also getting IconButtonProps. Let's remove that.
What we don't want is ButtonProps to be prefixed by any alphabets.
`import .*[^a-zA-Z]ButtonProps.*from '.*Button';`

Now our search is only showing ButtonProps without any noise.
 
### Replace regex in VSCode
Now let's say you want to rename the `Button` component to `Btn`.
We will need to replace these three occurrences:
1. imports (`import Button from 'Button'`)
2. Usage (`<Button ></Button>`)
3. Assignments (`const MyComponent = Button`)

**********
<center>Lets start.</center>
**********

#### 1. imports
Here the `()` are capture groups that we will access using $1, $2 respectively.
![Find and replace imports](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5jitl0bj7tx98445etln.png)
 
This is what VSCode will show you:
![VSCode rename component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5r76valt3jq7muye57x.png)
- What we have done here is select everything between `import` and `Button` by first capture group, then everything between `Button` and `from` by second capture group, and so on.
- Then we carefully want to replace only Button with Btn.
- So we replaced the first capture group with itself ($1), the second one with $2, the third one with $3.
- Hence we get our replacement string `import$1Button$2from '$3Button';`.
- Now change `Button` to `Btn`, and we get `import$1Btn$2from '$3Button';`.

And your button imports are now renamed.
#### 2. Usage
Continuing on above.
![Find and replace usage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/csy0ymhf011lddkq1xgo.png)
 
Find `<Button` that does not have trailing alphabets (to omit something like `<ButtonGroup` and maybe have a trailing newline. then replace all of them with `<Btn$1` i.e. using $1, replace `space` with space, newline with a newline.

End bracket now
![Find and replace end bracket](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kecpog2hqxf105r6zeop.png)

This is pretty easy, but why ` *`. Since `</Button>`, `</ Button>` and `</Button >` all are valid JSX.
But why not $1, or $2. Since this will also clean up the code and replace all the above with clean `<Btn>`.

#### 3. Assignments
This one should not be that much in your code, and you can directly search for `Button` now.
Find - `Button[^']`

But what is `[^']` for? To exclude all the occurrences of `import.*from 'Button';`.

### Conclusion
With this, all our occurrences of Button are now Btn. And we now understand Regex a little better and use it to make our work easy.

In the future, I'll also try to write some articles highlighting more use-cases of regex to make your life easier.

***
## Read Next
{% post piyushkmr/enforce-git-messages-format-without-throwing-everyone-off-552 %}