You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 9-regular-expressions/10-regexp-greedy-and-lazy/article.md
+56-56Lines changed: 56 additions & 56 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ Prendiamo ad esempio la seguente esercitazione.
8
8
9
9
Abbiamo bisogno di rimpiazzare tutti i doppi apici `"..."` in un testo con le virgolette basse: `«...»`, che sono preferite nella tipografia di molti paesi.
10
10
11
-
Ad esempio: `"Hello, world"` dovrebbe diventare `«Hello, world»`. Esistono altre virgolette, come `„Witam, świat!”`(in Polonia) o `「你好,世界」`(in Cina), in questo caso, tuttavia, scegliamo `«...»`.
11
+
Ad esempio: `"Hello, world"` dovrebbe diventare `«Hello, world»`. Esistono altre virgolette, come `„Witam, świat!”` in Polonia o `「你好,世界」` in Cina, in questo caso, tuttavia, scegliamo `«...»`.
12
12
13
13
Innanzitutto dobbiamo individuare le stringhe tra doppi apici per poi sostituirli.
14
14
@@ -24,15 +24,15 @@ let str = 'a "witch" and her "broom" is one';
24
24
alert( str.match(regexp) ); // "witch" and her "broom"
25
25
```
26
26
27
-
...Non funziona come desideravamo!
27
+
Non funziona come desideravamo!
28
28
29
29
Invece di trovare i due riscontri `match:"witch"` e `match:"broom"`, ne trova solo uno: `match:"witch" and her "broom"`.
30
30
31
31
Questo fenomeno può essere descritto così: "l'avidità è la causa di tutti i mali".
32
32
33
33
## La ricerca in modalità greedy (avida)
34
34
35
-
Per trovare un riscontro, il motore dell'espressione regolare usa il seguente algoritmo:
35
+
Per trovare un riscontro, l'interprete dell'espressione regolare usa il seguente algoritmo:
36
36
37
37
- Per ogni posizione nella stringa
38
38
- Prova a trovare un riscontro del pattern in quella posizione.
@@ -42,27 +42,27 @@ Questa procedura generica non ci spiega con evidenza perché l'espressione regol
42
42
43
43
1. Il primo carattere del pattern è un doppio apice `pattern:"`.
44
44
45
-
Il motore dell'espressione regolare prova a trovarlo nella posizione zero della stringa `subject:a "witch" and her "broom" is one`, ma in quel punto trova `subject:a`, pertanto non c'è immediata corrispondenza.
45
+
L'interprete dell'espressione regolare prova a trovarlo nella posizione zero della stringa `subject:a "witch" and her "broom" is one`, ma in quel punto trova `subject:a`, pertanto non c'è immediata corrispondenza.
46
46
47
47
Quindi procede: passa alle successive posizioni nella stringa sorgente e prova a trovare lì il primo carattere del pattern, prima fallisce nuovamente, e poi trova finalmente il doppio apice nella terza posizione:
48
48
49
49

50
50
51
-
2. Rilevato il doppio apice, il motore tenta di trovare riscontro per il resto del pattern. Verifica se il resto della stringa sia conforme a `pattern:.+"`.
51
+
2. Rilevato il doppio apice, tenta di trovare riscontro per il resto del pattern. Verifica se il resto della stringa sia conforme a `pattern:.+"`.
52
52
53
53
Nel nostro esempio il successivo carattere del pattern è `pattern:.` (un punto) che indica "qualsiasi carattere tranne una nuova riga". Trova pertanto corrispondenza nel carattere successivo della stringa `match:'w'`:
54
54
55
55

56
56
57
-
3. Successivamente il punto trova ulteriori riscontri per via del quantificatore `pattern:.+`. Il motore dell'espressione regolare aggiunge un carattere dopo l'altro.
57
+
3. Successivamente il punto trova ulteriori riscontri per via del quantificatore `pattern:.+`. L'interprete dell'espressione regolare aggiunge un carattere dopo l'altro.
58
58
59
-
...Fino a quando? Tutti i caratteri corrispondono al punto, quindi si ferma solo quando raggiunge la fine della stringa:
59
+
Fino a quando? Tutti i caratteri corrispondono al punto, quindi si ferma solo quando raggiunge la fine della stringa:
60
60
61
61

62
62
63
-
4. A questo punto il motore cessa di ripetere `pattern:.+` e prova a trovare il prossimo carattere del pattern. Si tratta del doppio apice `pattern:"`. C'è un problema però: la stringa è finita, non ci sono più caratteri!
63
+
4. A questo punto cessa di ripetere `pattern:.+` e prova a trovare il prossimo carattere del pattern. Si tratta del doppio apice `pattern:"`. C'è un problema però: la stringa è finita, non ci sono più caratteri!
64
64
65
-
Il motore dell'espressione regolare capisce di aver preso troppi caratteri per `pattern:.+` e comincia a *retrocedere*.
65
+
L'interprete dell'espressione regolare capisce di aver preso troppi caratteri per `pattern:.+` e comincia a *retrocedere*.
66
66
67
67
In altre parole accorcia di un carattere la corrispondenza per il quantificatore:
68
68
@@ -72,13 +72,13 @@ Questa procedura generica non ci spiega con evidenza perché l'espressione regol
72
72
73
73
Se ci fosse stato un doppio apice, la ricerca sarebbe terminata, ma l'ultima carattere è una `subject:'e'`, nessun riscontro quindi.
74
74
75
-
5....Allora il motore diminuisce di un ulteriore carattere il numero delle ripetizioni di `pattern:.+`:
75
+
5. Allora l'interprete diminuisce di un ulteriore carattere il numero delle ripetizioni di `pattern:.+`:
76
76
77
77

78
78
79
79
Anche il carattere `subject:'n'` non soddisfa la ricerca di `pattern:'"'`.
80
80
81
-
6.Il motore continua a retrocedere: diminuisce le ripetizioni per `pattern:'.'` finché il resto del pattern (nel nostro caso `pattern:'"'`) non trova riscontro:
81
+
6.L'interprete continua a retrocedere: diminuisce le ripetizioni per `pattern:'.'` finché il resto del pattern (nel nostro caso `pattern:'"'`) non trova riscontro:
82
82
83
83

84
84
@@ -90,7 +90,7 @@ Probabilmente non è quello che ci aspettavamo, ma funziona così.
90
90
91
91
**In modalità greedy (quella predefinita) un quantificatore viene ripetuto quante più volte possibile.**
92
92
93
-
Il motore della regexp aggiunge quanti più caratteri possibili alla corrispondenza con `pattern:.+`, successivamente retrocede di un carattere alla volta se il resto del pattern non trova riscontro.
93
+
L'interprete della regexp aggiunge quanti più caratteri possibili alla corrispondenza con `pattern:.+`, successivamente retrocede di un carattere alla volta se il resto del pattern non trova riscontro.
94
94
95
95
L'obiettivo della nostra esercitazione non è questo, proprio in questi casi viene in soccorso la modalità lazy.
96
96
@@ -118,16 +118,16 @@ Per comprendere distintamente cosa sia cambiato, seguiamo la ricerca passo dopo
118
118
119
119

120
120
121
-
2. Anche il secondo step è simile: il motore trova una corrispondenza per il punto `pattern:'.'`:
121
+
2. Anche il secondo step è simile: l'interprete trova una corrispondenza per il punto `pattern:'.'`:
122
122
123
123

124
124
125
-
3. Da questo punto la ricerca procede in modo differente. Dal momento che il quantificatore è in modalità lazy `pattern:+?`, il motore non prova a cercare il punto più di una volta, si ferma e cerca subito la corrispondenza con il resto del pattern `pattern:'"'`:
125
+
3. Da questo punto la ricerca procede in modo differente. Dal momento che il quantificatore è in modalità lazy `pattern:+?`, l'interprete non prova a cercare il punto più di una volta, si ferma e cerca subito la corrispondenza con il resto del pattern `pattern:'"'`:
126
126
127
127

128
128
129
129
Se ci fosse un doppio apice a questo punto la ricerca sarebbe già terminata, ma c'è una `'i'` e quindi nessuna corrispondenza.
130
-
4.Il motore della regexp allora aumenta il numero delle ripetizioni per il punto e riprova:
130
+
4.L'interprete della regexp allora aumenta il numero delle ripetizioni per il punto e riprova:
131
131
132
132

133
133
@@ -140,7 +140,7 @@ Per comprendere distintamente cosa sia cambiato, seguiamo la ricerca passo dopo
140
140
141
141

142
142
143
-
In questo esempio abbiamo visto come funziona la modalità lazy per `pattern:+?`. I quantificatori `pattern:*?` e `pattern:??` operano in modo simile: il motore della regexp aumenta il numero delle ripetizioni solo se il resto del pattern non ha corrispondenza in una data posizione.
143
+
In questo esempio abbiamo visto come funziona la modalità lazy per `pattern:+?`. I quantificatori `pattern:*?` e `pattern:??` operano in modo simile: aumentano il numero delle ripetizioni solo se il resto del pattern non ha corrispondenza in una data posizione.
144
144
145
145
**La modalità lazy è abilitata unicamente per il quantificatore seguito da `?`.**
2. Segue la corrispondenza dello spazio nel pattern.
157
157
3. A questo punto c'è `pattern:\d+?`. Il quantificatore è modalità lazy, perciò trova solo una cifra `match:4` e prova a verificare se il resto del pattern è soddisfatto.
158
158
159
-
...Nel pattern, tuttavia, non c'è niente dopo `pattern:\d+?`.
159
+
Nel pattern, tuttavia, non c'è niente dopo `pattern:\d+?`.
160
160
161
161
La modalità lazy non ripete nulla se non c'è un motivo. Il pattern è finito e conclude la ricerca. La nostra corrispondenza è `match:123 4`.
162
162
@@ -168,11 +168,11 @@ Ma per comprendere come funzionino le espressioni regolari e come implementarle
168
168
Del resto è difficile ottimizzare le espressioni regolari complesse, pertanto la ricerca potrebbe anche funzionare esattamente come indicato.
169
169
```
170
170
171
-
## Approccio alternativo
171
+
## Un approccio alternativo
172
172
173
-
With regexps, there's often more than one way to do the same thing.
173
+
Con le espressioni regolari, spesso c'è più di un modo di ottenere lo stesso risultato.
174
174
175
-
In our case we can find quoted strings without lazy mode using the regexp `pattern:"[^"]+"`:
175
+
Nel nostro caso potremmo trovare le stringhe tra doppi apici senza la modalità lazy, usando la regexp `pattern:"[^"]+"`:
176
176
177
177
```js run
178
178
let regexp =/"[^"]+"/g;
@@ -182,120 +182,120 @@ let str = 'a "witch" and her "broom" is one';
182
182
alert( str.match(regexp) ); // "witch", "broom"
183
183
```
184
184
185
-
The regexp `pattern:"[^"]+"`gives correct results, because it looks for a quote `pattern:'"'` followed by one or more non-quotes `pattern:[^"]`, and then the closing quote.
185
+
La regexp `pattern:"[^"]+"`dà il risultato corretto, perché cerca un doppio apice `pattern:'"'`, seguito da uno o più caratteri che non siano doppi apici `pattern:[^"]` e successivamente un doppio apice di chiusura.
186
186
187
-
When the regexp engine looks for `pattern:[^"]+`it stops the repetitions when it meets the closing quote, and we're done.
187
+
Quando l'interprete della regexp cerca `pattern:[^"]+`si arresta quando incontra il doppio apice di chiusura e termina il suo lavoro.
188
188
189
-
Please note, that this logic does not replace lazy quantifiers!
189
+
Si noti che questa logica non rimpiazza i quantificatori lazy!
190
190
191
-
It is just different. There are times when we need one or another.
191
+
Sono due approcci differenti. Talvolta ci serve uno, a volte l'altro.
192
192
193
-
**Let's see an example where lazy quantifiers fail and this variant works right.**
193
+
**Guardiamo un esempio in cui i quantificatori lazy falliscono e questa variante funziona a dovere.**
194
194
195
-
For instance, we want to find links of the form`<a href="..." class="doc">`, with any`href`.
195
+
Se volessimo, per esempio, trovare dei link di questo tipo`<a href="..." class="doc">`, con qualsiasi contenuto per`href`.
196
196
197
-
Which regular expression to use?
197
+
Quale espressione regolare dovremmo usare?
198
198
199
-
The first idea might be: `pattern:/<a href=".*" class="doc">/g`.
199
+
La prima idea potrebbe essere: `pattern:/<a href=".*" class="doc">/g`.
So, we need the pattern to look for `<a href="...something..." class="doc">`, but both greedy and lazy variants have problems.
275
+
Ricapitoliamo, abbiamo bisogno del pattern per cercare `<a href="...something..." class="doc">`, ma entrambe le varianti greedy e lazy danno problemi.
276
276
277
-
The correct variant can be: `pattern:href="[^"]*"`. It will take all characters inside the`href`attribute till the nearest quote, just what we need.
277
+
Un'alternativa corretta potrebbe essere: `pattern:href="[^"]*"`. Essa prenderà tutti i caratteri dentro l'attributo`href`fino al doppio apice più vicino. Proprio quello di cui abbiamo bisogno!
278
278
279
-
A working example:
279
+
Ecco un esempio funzionante:
280
280
281
281
```js run
282
282
let str1 ='...<a href="link1" class="wrong">... <p style="" class="doc">...';
283
283
let str2 ='...<a href="link1" class="doc">... <a href="link2" class="doc">...';
284
284
let regexp =/<a href="[^"]*" class="doc">/g;
285
285
286
-
//Works!
287
-
alert( str1.match(regexp) ); // null, no matches, that's correct
286
+
//Funziona!
287
+
alert( str1.match(regexp) ); // null, è corretto che non ci sia alcun riscontro
I quantificatori possono funzionare in due modalità differenti:
294
294
295
295
Greedy
296
-
: By default the regular expression engine tries to repeat the quantified character as many times as possible. For instance, `pattern:\d+`consumes all possible digits. When it becomes impossible to consume more (no more digits or string end), then it continues to match the rest of the pattern. If there's no match then it decreases the number of repetitions (backtracks) and tries again.
296
+
: L'interprete delle espressioni regolari, in via predefinita, prova a ripetere un quantificatore quante più volte possibile. Per esempio, `pattern:\d+`considera tutte le cifre disponibili. Quando diventa impossibile trovarne ancora (non ci sono più cifre o è finita la stringa), allora continua a cercare la corrispondenza con il resto del pattern. Se non trova riscontro allora retrocede, diminuisce il numero di ripetizioni e prova ancora.
297
297
298
298
Lazy
299
-
: Enabled by the question mark `pattern:?`after the quantifier. The regexp engine tries to match the rest of the pattern before each repetition of the quantified character.
299
+
: Abilitata dal punto interrogativo `pattern:?`dopo il quantificatore. L'interprete delle regexp prova la corrispondenza del resto del pattern prima di ogni ripetizione di un carattere quantificato.
300
300
301
-
As we've seen, the lazy mode is not a "panacea" from the greedy search. An alternative is a "fine-tuned" greedy search, with exclusions, as in the pattern `pattern:"[^"]+"`.
301
+
Come abbiamo visto, la modalità lazy non è una "panacea" per i problemi della ricerca greedy. Un'alternativa può essere una ricerca greedy "calibrata", avvalendoci di esclusioni come nel pattern `pattern:"[^"]+"`.
0 commit comments