Skip to content

Commit 331d700

Browse files
authored
Merge pull request #144 from odsantos/fix-reg-expressions
Update folder 9-regular-expressions
2 parents 35cf660 + 1924dd9 commit 331d700

File tree

69 files changed

+3450
-97
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+3450
-97
lines changed
Lines changed: 110 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,65 @@
11
# Patterns and flags
22

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

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

7-
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.
8-
9-
## Regular expressions
7+
## Regular Expressions
108

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

13-
There are two syntaxes to create a regular expression object.
11+
There are two syntaxes that can be used to create a regular expression object.
1412

15-
The long syntax:
13+
The "long" syntax:
1614

1715
```js
1816
regexp = new RegExp("pattern", "flags");
1917
```
2018

21-
...And the short one, using slashes `"/"`:
19+
And the "short" one, using slashes `"/"`:
2220

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

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

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

32-
To search inside a string, we can use method [search](mdn:js/String/search).
30+
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.
3331

34-
Here's an example:
32+
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:
3533

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

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

43-
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.
40+
## Flags
4441

45-
The code above is the same as:
42+
Regular expressions may have flags that affect the search.
4643

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

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

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

56-
But that's only for now. Soon we'll create more complex regular expressions with much more searching power.
52+
`pattern:m`
53+
: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).
54+
55+
`pattern:s`
56+
: Enables "dotall" mode, that allows a dot `pattern:.` to match newline character `\n` (covered in the chapter <info:regexp-character-classes>).
57+
58+
`pattern:u`
59+
: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
60+
61+
`pattern:y`
62+
: "Sticky" mode: searching at the exact position in the text (covered in the chapter <info:regexp-sticky>)
5763

5864
```smart header="Colors"
5965
From here on the color scheme is:
@@ -63,65 +69,109 @@ From here on the color scheme is:
6369
- result -- `match:green`
6470
```
6571

72+
## Searching: str.match
6673

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

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

72-
Here's an example of a dynamically generated regexp:
78+
It has 3 working modes:
7379

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

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

88+
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:
89+
```js run
90+
let str = "We will, we will rock you";
8391
84-
## Flags
92+
let result = str.match(/we/i); // without flag g
8593
86-
Regular expressions may have flags that affect the search.
94+
alert( result[0] ); // We (1st match)
95+
alert( result.length ); // 1
8796
88-
There are only 5 of them in JavaScript:
97+
// Details:
98+
alert( result.index ); // 0 (position of the match)
99+
alert( result.input ); // We will, we will rock you (source string)
100+
```
101+
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>.
89102

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

93-
`g`
94-
: With this flag the search looks for all matches, without it -- only the first one (we'll see uses in the next chapter).
105+
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.:
95106
96-
`m`
97-
: Multiline mode (covered in the chapter <info:regexp-multiline-mode>).
107+
```js run
108+
let matches = "JavaScript".match(/HTML/); // = null
98109
99-
`s`
100-
: "Dotall" mode, allows `.` to match newlines (covered in the chapter <info:regexp-character-classes>).
110+
if (!matches.length) { // Error: Cannot read property 'length' of null
111+
alert("Error in the line above");
112+
}
113+
```
101114
102-
`u`
103-
: Enables full unicode support. The flag enables correct processing of surrogate pairs. More about that in the chapter <info:regexp-unicode>.
115+
If we'd like the result to always be an array, we can write it this way:
116+
117+
```js run
118+
let matches = "JavaScript".match(/HTML/)*!* || []*/!*;
119+
120+
if (!matches.length) {
121+
alert("No matches"); // now it works
122+
}
123+
```
124+
125+
## Replacing: str.replace
126+
127+
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).
128+
129+
For instance:
104130
105-
`y`
106-
: Sticky mode (covered in the chapter <info:regexp-sticky>)
131+
```js run
132+
// no flag g
133+
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
134+
135+
// with flag g
136+
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
137+
```
138+
139+
The second argument is the `replacement` string. We can use special character combinations in it to insert fragments of the match:
107140
108-
We'll cover all these flags further in the tutorial.
141+
| Symbols | Action in the replacement string |
142+
|--------|--------|
143+
|`$&`|inserts the whole match|
144+
|<code>$&#096;</code>|inserts a part of the string before the match|
145+
|`$'`|inserts a part of the string after the match|
146+
|`$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>|
147+
|`$<name>`|inserts the contents of the parentheses with the given `name`, more about it in the chapter <info:regexp-groups>|
148+
|`$$`|inserts character `$` |
109149
110-
For now, the simplest flag is `i`, here's an example:
150+
An example with `pattern:$&`:
111151
112152
```js run
113-
let str = "I love JavaScript!";
153+
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
154+
```
155+
156+
## Testing: regexp.test
114157
115-
alert( str.search(/LOVE/i) ); // 2 (found lowercased)
158+
The method `regexp.test(str)` looks for at least one match, if found, returns `true`, otherwise `false`.
159+
160+
```js run
161+
let str = "I love JavaScript";
162+
let regexp = /LOVE/i;
116163

117-
alert( str.search(/LOVE/) ); // -1 (nothing found without 'i' flag)
164+
alert( regexp.test(str) ); // true
118165
```
119166
120-
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.
167+
Later in this chapter we'll study more regular expressions, walk through more examples, and also meet other methods.
121168
169+
Full information about the methods is given in the article <info:regexp-methods>.
122170
123171
## Summary
124172
125-
- A regular expression consists of a pattern and optional flags: `g`, `i`, `m`, `u`, `s`, `y`.
126-
- Without flags and special symbols that we'll study later, the search by a regexp is the same as a substring search.
127-
- 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.
173+
- A regular expression consists of a pattern and optional flags: `pattern:g`, `pattern:i`, `pattern:m`, `pattern:u`, `pattern:s`, `pattern:y`.
174+
- Without flags and special symbols (that we'll study later), the search by a regexp is the same as a substring search.
175+
- The method `str.match(regexp)` looks for matches: all of them if there's `pattern:g` flag, otherwise, only the first one.
176+
- 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.
177+
- The method `regexp.test(str)` returns `true` if there's at least one match, otherwise, it returns `false`.

0 commit comments

Comments
 (0)