Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
4406f0f
components
iliakan Apr 2, 2019
8bb418b
Merge branch 'refactor'
iliakan Apr 2, 2019
3d73f44
Update article.md
overken Apr 3, 2019
a03121a
Sketch editor update (no important image changes)
iliakan Apr 5, 2019
07a77ca
Type in 22-regexp-sticky/article.md
HaydenLobry Apr 11, 2019
a00b7b6
Just remove a strange symbol
oshliaer Apr 14, 2019
08b6e9e
minor
iliakan Apr 20, 2019
298faa0
Fix name of JavaScript
lex111 Apr 23, 2019
f5d5655
up
iliakan Apr 25, 2019
55e0f23
minor
iliakan Apr 25, 2019
6a93712
minor
iliakan Apr 25, 2019
0521fd6
minor
iliakan Apr 25, 2019
1961c2a
regexp-character-classes: wording
lex111 Apr 27, 2019
08b9119
21-regexp-unicode-properties: fix title
lex111 Apr 30, 2019
f6d8a2f
Merge pull request #946 from javascript-tutorial/lex111-patch-2
iliakan Apr 30, 2019
ece5bac
Regex: moved and deleted content from the "Patterns and flags".
luc4leone May 6, 2019
02e2e7f
fix
iliakan May 9, 2019
7c0f5ea
fixes
iliakan May 9, 2019
b2601c3
minor
iliakan May 9, 2019
8f2b808
Fix typos
lex111 May 12, 2019
6072dc0
Fix typos
lex111 May 13, 2019
61ea833
Fix typo
lex111 May 13, 2019
f513196
up
iliakan May 15, 2019
6f33182
minor
iliakan May 15, 2019
1ff164e
Fix a little typo.
May 19, 2019
df779a6
minor
iliakan May 19, 2019
75f50bd
minor
iliakan May 20, 2019
3fe3ae9
minor
iliakan May 21, 2019
583d513
Change number of flags
vasilevx May 27, 2019
7027b47
minor
iliakan May 28, 2019
a440bc4
Fix typo
segayuu Jun 3, 2019
2107c48
fixes
iliakan Jun 3, 2019
4ec9782
fixes #1041
iliakan Jun 7, 2019
a28bef8
regexp
iliakan Jun 10, 2019
497d844
fixes
iliakan Jun 25, 2019
b07b445
fixes
iliakan Jun 26, 2019
dbe238d
fixes
iliakan Jun 26, 2019
7b9d5a8
Fix English
Jun 27, 2019
2cf9471
Correct spelling
Jun 28, 2019
32e12c9
Fix spelling and grammar
Jun 28, 2019
b457692
Fix grammar
Jun 28, 2019
062015e
minor
iliakan Jul 1, 2019
9679493
minor
iliakan Jul 5, 2019
72227be
regexp task
iliakan Jul 24, 2019
941396f
minor
iliakan Jul 24, 2019
f034165
fixes
iliakan Jul 25, 2019
38a1154
fixes
iliakan Jul 25, 2019
8575e43
images to svg
iliakan Jul 28, 2019
be6ad9c
typo
iliakan Aug 4, 2019
86382f2
Embed font to SVG
iliakan Aug 11, 2019
b267485
minor
iliakan Aug 11, 2019
a1eab02
minor
iliakan Aug 14, 2019
8de599f
minor
iliakan Aug 14, 2019
d61b9f3
minor
iliakan Aug 15, 2019
d139343
Update article.md
alevmo Aug 19, 2019
ac3791c
Change "occasionally" to "accidentally"
paroche Aug 20, 2019
986a5fc
minor
iliakan Aug 21, 2019
103b650
minor
iliakan Sep 2, 2019
a9d7fc8
WIP
iliakan Sep 4, 2019
4f03133
WIP
iliakan Sep 4, 2019
1491c39
WIP
iliakan Sep 5, 2019
760cb73
regexp
iliakan Sep 5, 2019
d0c46d6
WIP
iliakan Sep 6, 2019
33807c9
reg->regexp
iliakan Sep 6, 2019
71283e0
WIP
iliakan Sep 6, 2019
808552d
fix
iliakan Sep 7, 2019
01b61e0
fix
iliakan Oct 10, 2019
c6dd942
fix
iliakan Oct 10, 2019
14b9120
fix
iliakan Oct 10, 2019
f135c27
fix
iliakan Oct 10, 2019
a8f7f93
fix
iliakan Oct 10, 2019
4458ac9
fix
iliakan Oct 10, 2019
cfcad53
fix
iliakan Oct 10, 2019
9e50304
fix
iliakan Oct 10, 2019
6327a46
re-import images from Sketch (no changes)
iliakan Oct 10, 2019
ff934a1
Update solution.md
iliakan Oct 10, 2019
d13bb2b
Update article.md
iliakan Oct 17, 2019
df93a71
minor
iliakan Oct 21, 2019
8871fd5
removes russian text chunk from english text
TobiObeck Oct 29, 2019
748e97b
Update 01-regexp-introduction
wgolledge Nov 5, 2019
503e43f
Update article.md
lex111 Dec 19, 2019
bc11451
Translated tasks to English
imabp Jan 14, 2020
e806048
Translated line 10 content to English
imabp Jan 14, 2020
a77e784
Translated Solution from Russian to English
imabp Jan 14, 2020
7149d1f
Translated to English and updated.
imabp Jan 14, 2020
c1f22a3
minor fixes
iliakan Jan 19, 2020
055a155
Fixing a typo
sohailashraf003 Jan 29, 2020
cfb56cd
adding the `[^]` pattern
KennethKinLum Jan 29, 2020
2d48088
Merge pull request #1729 from KennethKinLum/patch-8
iliakan Feb 5, 2020
f11d17b
minor fixes
iliakan Feb 5, 2020
4878991
minor fixes
iliakan Feb 5, 2020
89e3860
Typo fix
Invariance-NaN Feb 10, 2020
c5d1082
Fix typo
YRFT Feb 29, 2020
1bbd818
fix typo
KuthumiPepple Mar 3, 2020
1683870
fix: 2 lines of russian to english and a typo (mathces -> matches)
HynekS Mar 11, 2020
ea406ab
Merge pull request #1787 from KuthumiPepple/patch-1
iliakan Mar 21, 2020
6f7e928
Merge pull request #1796 from HynekS/fix-lang-and-typo
iliakan Mar 21, 2020
8a0d30a
Merge pull request #1744 from qdflavel/typos-fix
lex111 Mar 29, 2020
b922026
fixes #1836
iliakan Apr 2, 2020
5b684eb
fix typo
baooab Apr 5, 2020
7c5a987
delete extra content
baooab Apr 21, 2020
dce80e4
Adding missing 'pattern:'
Aakodal May 8, 2020
c88d67d
closes #1882
iliakan May 17, 2020
648ba60
correct minor error
ZYinMD May 18, 2020
7aa3d6c
correct minor error: "имя" is used in place of "name"
ZYinMD May 19, 2020
5eda024
Merge pull request #1914 from ZYinMD/patch-2
iliakan May 23, 2020
bfbf4b3
Update folder 9-regular-expressions
odsantos May 25, 2020
1924dd9
Merge branch 'master' of en.javascript.info into and update fix-reg-e…
odsantos May 25, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 110 additions & 60 deletions 9-regular-expressions/01-regexp-introduction/article.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,65 @@
# Patterns and flags

Regular expressions is a powerful way of searching and replacing inside a string.
Regular expressions are patterns that provide a powerful way to search and replace in text.

In JavaScript regular expressions are implemented using objects of a built-in `RegExp` class and integrated with strings.
In JavaScript, they are available via the [RegExp](mdn:js/RegExp) object, as well as being integrated in methods of strings.

Please note that regular expressions vary between programming languages. In this tutorial we concentrate on JavaScript. Of course there's a lot in common, but they are a somewhat different in Perl, Ruby, PHP etc.

## Regular expressions
## Regular Expressions

A regular expression (also "regexp", or just "reg") consists of a *pattern* and optional *flags*.

There are two syntaxes to create a regular expression object.
There are two syntaxes that can be used to create a regular expression object.

The long syntax:
The "long" syntax:

```js
regexp = new RegExp("pattern", "flags");
```

...And the short one, using slashes `"/"`:
And the "short" one, using slashes `"/"`:

```js
regexp = /pattern/; // no flags
regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
```

Slashes `"/"` tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings.
Slashes `pattern:/.../` tell JavaScript that we are creating a regular expression. They play the same role as quotes for strings.

## Usage
In both cases `regexp` becomes an instance of the built-in `RegExp` class.

To search inside a string, we can use method [search](mdn:js/String/search).
The main difference between these two syntaxes is that pattern using slashes `/.../` does not allow for expressions to be inserted (like string template literals with `${...}`). They are fully static.

Here's an example:
Slashes are used when we know the regular expression at the code writing time -- and that's the most common situation. While `new RegExp`, is more often used when we need to create a regexp "on the fly" from a dynamically generated string. For instance:

```js run
let str = "I love JavaScript!"; // will search here
```js
let tag = prompt("What tag do you want to find?", "h2");

let regexp = /love/;
alert( str.search(regexp) ); // 2
let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above
```

The `str.search` method looks for the pattern `pattern:/love/` and returns the position inside the string. As we might guess, `pattern:/love/` is the simplest possible pattern. What it does is a simple substring search.
## Flags

The code above is the same as:
Regular expressions may have flags that affect the search.

```js run
let str = "I love JavaScript!"; // will search here
There are only 6 of them in JavaScript:

let substr = 'love';
alert( str.search(substr) ); // 2
```
`pattern:i`
: With this flag the search is case-insensitive: no difference between `A` and `a` (see the example below).

So searching for `pattern:/love/` is the same as searching for `"love"`.
`pattern:g`
: With this flag the search looks for all matches, without it -- only the first match is returned.

But that's only for now. Soon we'll create more complex regular expressions with much more searching power.
`pattern:m`
: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).

`pattern:s`
: Enables "dotall" mode, that allows a dot `pattern:.` to match newline character `\n` (covered in the chapter <info:regexp-character-classes>).

`pattern:u`
: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.

`pattern:y`
: "Sticky" mode: searching at the exact position in the text (covered in the chapter <info:regexp-sticky>)

```smart header="Colors"
From here on the color scheme is:
Expand All @@ -63,65 +69,109 @@ From here on the color scheme is:
- result -- `match:green`
```

## Searching: str.match

````smart header="When to use `new RegExp`?"
Normally we use the short syntax `/.../`. But it does not support variable insertions `${...}`.
As mentioned previously, regular expressions are integrated with string methods.

On the other hand, `new RegExp` allows to construct a pattern dynamically from a string, so it's more flexible.
The method `str.match(regexp)` finds all matches of `regexp` in the string `str`.

Here's an example of a dynamically generated regexp:
It has 3 working modes:

```js run
let tag = prompt("Which tag you want to search?", "h2");
let regexp = new RegExp(`<${tag}>`);
1. If the regular expression has flag `pattern:g`, it returns an array of all matches:
```js run
let str = "We will, we will rock you";

// finds <h2> by default
alert( "<h1> <h2> <h3>".search(regexp));
```
````
alert( str.match(/we/gi) ); // We,we (an array of 2 substrings that match)
```
Please note that both `match:We` and `match:we` are found, because flag `pattern:i` makes the regular expression case-insensitive.

2. If there's no such flag it returns only the first match in the form of an array, with the full match at index `0` and some additional details in properties:
```js run
let str = "We will, we will rock you";

## Flags
let result = str.match(/we/i); // without flag g

Regular expressions may have flags that affect the search.
alert( result[0] ); // We (1st match)
alert( result.length ); // 1

There are only 5 of them in JavaScript:
// Details:
alert( result.index ); // 0 (position of the match)
alert( result.input ); // We will, we will rock you (source string)
```
The array may have other indexes, besides `0` if a part of the regular expression is enclosed in parentheses. We'll cover that in the chapter <info:regexp-groups>.

`i`
: With this flag the search is case-insensitive: no difference between `A` and `a` (see the example below).
3. And, finally, if there are no matches, `null` is returned (doesn't matter if there's flag `pattern:g` or not).

`g`
: With this flag the search looks for all matches, without it -- only the first one (we'll see uses in the next chapter).
This a very important nuance. If there are no matches, we don't receive an empty array, but instead receive `null`. Forgetting about that may lead to errors, e.g.:

`m`
: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).
```js run
let matches = "JavaScript".match(/HTML/); // = null

`s`
: "Dotall" mode, allows `.` to match newlines (covered in the chapter <info:regexp-character-classes>).
if (!matches.length) { // Error: Cannot read property 'length' of null
alert("Error in the line above");
}
```

`u`
: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
If we'd like the result to always be an array, we can write it this way:

```js run
let matches = "JavaScript".match(/HTML/)*!* || []*/!*;

if (!matches.length) {
alert("No matches"); // now it works
}
```

## Replacing: str.replace

The method `str.replace(regexp, replacement)` replaces matches found using `regexp` in string `str` with `replacement` (all matches if there's flag `pattern:g`, otherwise, only the first one).

For instance:

`y`
: Sticky mode (covered in the chapter <info:regexp-sticky>)
```js run
// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will

// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
```

The second argument is the `replacement` string. We can use special character combinations in it to insert fragments of the match:

We'll cover all these flags further in the tutorial.
| Symbols | Action in the replacement string |
|--------|--------|
|`$&`|inserts the whole match|
|<code>$&#096;</code>|inserts a part of the string before the match|
|`$'`|inserts a part of the string after the match|
|`$n`|if `n` is a 1-2 digit number, then it inserts the contents of n-th parentheses, more about it in the chapter <info:regexp-groups>|
|`$<name>`|inserts the contents of the parentheses with the given `name`, more about it in the chapter <info:regexp-groups>|
|`$$`|inserts character `$` |

For now, the simplest flag is `i`, here's an example:
An example with `pattern:$&`:

```js run
let str = "I love JavaScript!";
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
```

## Testing: regexp.test

alert( str.search(/LOVE/i) ); // 2 (found lowercased)
The method `regexp.test(str)` looks for at least one match, if found, returns `true`, otherwise `false`.

```js run
let str = "I love JavaScript";
let regexp = /LOVE/i;

alert( str.search(/LOVE/) ); // -1 (nothing found without 'i' flag)
alert( regexp.test(str) ); // true
```

So the `i` flag already makes regular expressions more powerful than a simple substring search. But there's so much more. We'll cover other flags and features in the next chapters.
Later in this chapter we'll study more regular expressions, walk through more examples, and also meet other methods.

Full information about the methods is given in the article <info:regexp-methods>.

## Summary

- A regular expression consists of a pattern and optional flags: `g`, `i`, `m`, `u`, `s`, `y`.
- Without flags and special symbols that we'll study later, the search by a regexp is the same as a substring search.
- The method `str.search(regexp)` returns the index where the match is found or `-1` if there's no match. In the next chapter we'll see other methods.
- A regular expression consists of a pattern and optional flags: `pattern:g`, `pattern:i`, `pattern:m`, `pattern:u`, `pattern:s`, `pattern:y`.
- Without flags and special symbols (that we'll study later), the search by a regexp is the same as a substring search.
- The method `str.match(regexp)` looks for matches: all of them if there's `pattern:g` flag, otherwise, only the first one.
- The method `str.replace(regexp, replacement)` replaces matches found using `regexp` with `replacement`: all of them if there's `pattern:g` flag, otherwise only the first one.
- The method `regexp.test(str)` returns `true` if there's at least one match, otherwise, it returns `false`.
Loading