2n-1
, where `n` is the length of the sequence.
+Ci sono molti modi di suddividere una sequenza di cifre `123456789` in numeri. Precisamente, ve ne sono sono 2n-1
, dove `n` è la lunghezza della sequenza.
-- For `123456789` we have `n=9`, that gives 511 combinations.
-- For a longer sequence with `n=20` there are about one million (1048575) combinations.
-- For `n=30` - a thousand times more (1073741823 combinations).
+- Per `123456789` abbiamo `n=9`, che dà 511 combinazioni.
+- Per una sequenza più lunga con `n=20` ci sono circa un milione di combinazioni (1048575).
+- Per `n=30` - mille volte tanto (1073741823 combinazioni).
-Trying each of them is exactly the reason why the search takes so long.
+Provare ciascuna di queste è esattamente la ragione per cui la ricerca impiega così tanto tempo.
-## Back to words and strings
+## Torniamo a parole e stringhe
-The similar thing happens in our first example, when we look for words by pattern `pattern:^(\w+\s?)*$` in the string `subject:An input that hangs!`.
+Una cosa simile accade nel nostro primo esempio, quando cerchiamo parole tramite il pattern `pattern:^(\w+\s?)*$` nella stringa `subject:An input that hangs!`.
-The reason is that a word can be represented as one `pattern:\w+` or many:
+Il motivo è che una parola può essere rappresentata come uno o più `pattern:\w+`:
```
(input)
@@ -172,63 +172,63 @@ The reason is that a word can be represented as one `pattern:\w+` or many:
...
```
-For a human, it's obvious that there may be no match, because the string ends with an exclamation sign `!`, but the regular expression expects a wordly character `pattern:\w` or a space `pattern:\s` at the end. But the engine doesn't know that.
+Per un essere umano è ovvio che possano mancare corrispondenze perché la stringa termina con un punto esclamativo `!`, ma per l'espressione regolare è atteso un carattere di una parola `pattern:\w` oppure uno spazio `pattern:\s` alla fine. Ma questo il motore non lo sa.
-It tries all combinations of how the regexp `pattern:(\w+\s?)*` can "consume" the string, including variants with spaces `pattern:(\w+\s)*` and without them `pattern:(\w+)*` (because spaces `pattern:\s?` are optional). As there are many such combinations (we've seen it with digits), the search takes a lot of time.
+Tenta tutte le combinazioni in cui la regexp `pattern:(\w+\s?)*` possa "consumare" la stringa, incluse le varianti con gli spazi `pattern:(\w+\s)*` e senza `pattern:(\w+)*` (perché gli spazi `pattern:\s?` sono opzionali). Poiché tali combinazioni sono molte (l'abbiamo visto con le cifre), la ricerca impiega un sacco di tempo.
-What to do?
+Cosa fare?
-Should we turn on the lazy mode?
+Dovremmo attivare la modalità lazy?
-Unfortunately, that won't help: if we replace `pattern:\w+` with `pattern:\w+?`, the regexp will still hang. The order of combinations will change, but not their total count.
+Sfortunatamente ciò non servirà: se sostituiamo `pattern:\w+` con `pattern:\w+?`, la regexp resterà ancora appesa. L'ordine delle combinazioni cambierà, ma non il loro numero totale.
-Some regular expression engines have tricky tests and finite automations that allow to avoid going through all combinations or make it much faster, but most engines don't, and it doesn't always help.
+Alcuni motori per espressioni regolari hanno test complicati e automazioni finite che permettono di evitare di considerare tutte le combinazioni o di velocizzare, ma la maggior parte dei motori non le ha e ciò non sempre aiuta.
-## How to fix?
+## Come risolvere?
-There are two main approaches to fixing the problem.
+Ci sono due approcci principali per risolvere il problema.
-The first is to lower the number of possible combinations.
+Il primo è ridurre il numero delle combinazioni possibili.
-Let's make the space non-optional by rewriting the regular expression as `pattern:^(\w+\s)*\w*$` - we'll look for any number of words followed by a space `pattern:(\w+\s)*`, and then (optionally) a final word `pattern:\w*`.
+Rendiamo lo spazio non-opzionale riscrivendo l'espressione regolare come `pattern:^(\w+\s)*\w*$` - cercheremo qualunque numero di parole seguite da uno spazio `pattern:(\w+\s)*`, e poi (opzionalmente) una parola finale `pattern:\w*`.
-This regexp is equivalent to the previous one (matches the same) and works well:
+Questa regexp è equivalente alla precedente (dà le stesse corrispondenze) e funziona bene:
```js run
let regexp = /^(\w+\s)*\w*$/;
let str = "An input string that takes a long time or even makes this regex hang!";
-alert( regexp.test(str) ); // false
+alert( regexp.test(str) ); // falso
```
-Why did the problem disappear?
+Perché il problema è sparito?
-That's because now the space is mandatory.
+Perché ora lo spazio è obbligatorio.
-The previous regexp, if we omit the space, becomes `pattern:(\w+)*`, leading to many combinations of `\w+` within a single word
+La precedente regexp, se omettiamo lo spazio, diviene `pattern:(\w+)*`, che porta a molte combinazioni di `\w+` con una singola parola.
-So `subject:input` could be matched as two repetitions of `pattern:\w+`, like this:
+Perciò `subject:input` può corrispondere a due ripetizioni di `pattern:\w+`, così:
```
\w+ \w+
(inp)(ut)
```
-The new pattern is different: `pattern:(\w+\s)*` specifies repetitions of words followed by a space! The `subject:input` string can't be matched as two repetitions of `pattern:\w+\s`, because the space is mandatory.
+Il nuovo pattern è differente: `pattern:(\w+\s)*` specifica ripetizioni di parole seguite da uno spazio! La stringa `subject:input` non può corrispondere a due ripetizioni di `pattern:\w+\s`, perché lo spazio è obbligatorio.
-The time needed to try a lot of (actually most of) combinations is now saved.
+Il tempo necessario per provare molte (di fatto la maggior parte) combinazioni è ora risparmiato.
-## Preventing backtracking
+## Prevenire il backtracking
-It's not always convenient to rewrite a regexp though. In the example above it was easy, but it's not always obvious how to do it.
+Non è sempre conveniente riscrivere una regexp, tuttavia. Nell'esempio sopra è stato facile, ma non è sempre ovvio come farlo.
-Besides, a rewritten regexp is usually more complex, and that's not good. Regexps are complex enough without extra efforts.
+Inoltre, una regexp riscritta è solitamente più complessa e questo non va bene. Le regexp sono abbastanza complesse senza ulteriori sforzi.
-Luckily, there's an alternative approach. We can forbid backtracking for the quantifier.
+Fortunatamente c'è un approccio alternativo. Possiamo proibire il backtracking per il quantificatore.
-The root of the problem is that the regexp engine tries many combinations that are obviously wrong for a human.
+La radice del problema è che il motore regexp prova molte combinazioni che sono ovviamente sbagliate per un umano.
-E.g. in the regexp `pattern:(\d+)*$` it's obvious for a human, that `pattern:+` shouldn't backtrack. If we replace one `pattern:\d+` with two separate `pattern:\d+\d+`, nothing changes:
+Ad es. nella regexp `pattern:(\d+)*$` è ovvio, per un umano, che `pattern:+` non dovrebbe operare alcun backtracking. Se rimpiazziamo un `pattern:\d+` con due `pattern:\d+\d+` separati non cambia nulla:
```
\d+........
@@ -238,81 +238,84 @@ E.g. in the regexp `pattern:(\d+)*$` it's obvious for a human, that `pattern:+`
(1234)(56789)!
```
-And in the original example `pattern:^(\w+\s?)*$` we may want to forbid backtracking in `pattern:\w+`. That is: `pattern:\w+` should match a whole word, with the maximal possible length. There's no need to lower the repetitions count in `pattern:\w+` or to split it into two words `pattern:\w+\w+` and so on.
+E nell'esempio originale `pattern:^(\w+\s?)*$` potremmo voler proibire il backtracking in `pattern:\w+`. Ovvero: `pattern:\w+` dovrebbe trovare una corrispondenza con una parola intera, con la massima lunghezza possibile. Non c'è alcun bisogno di ridurre il conteggio delle ripetizioni in `pattern:\w+` o spezzarlo in due parole `pattern:\w+\w+` e così via.
-Modern regular expression engines support possessive quantifiers for that. Regular quantifiers become possessive if we add `pattern:+` after them. That is, we use `pattern:\d++` instead of `pattern:\d+` to stop `pattern:+` from backtracking.
+I motori di espressioni regolari moderni supportano i quantificatori possessivi per questo. I quantificatori regolari divengono possessivi se aggiungiamo `pattern:+` dopo di essi. Cioè, usiamo `pattern:\d++` invece di `pattern:\d+` per evitare il backtracking di `pattern:+`.
-Possessive quantifiers are in fact simpler than "regular" ones. They just match as many as they can, without any backtracking. The search process without backtracking is simpler.
+Difatti, i quantificatori possessivi sono più semplici di quelli "regolari". Essi trovano quante più corrispondenze è possibile, senza alcun backtrack.
-There are also so-called "atomic capturing groups" - a way to disable backtracking inside parentheses.
+Ci sono anche i cosiddetti "atomic capturing groups" - un modo di disabilitare il backtracking all'interno delle parentesi.
-...But the bad news is that, unfortunately, in JavaScript they are not supported.
+...Ma la cattiva notizia è che, sfortunatamente, in JavaScript non sono supportati.
-We can emulate them though using a "lookahead transform".
+Possiamo emularli usando una "trasformazione lookahead".
-### Lookahead to the rescue!
+### Lookahead in soccorso!
-So we've come to real advanced topics. We'd like a quantifier, such as `pattern:+` not to backtrack, because sometimes backtracking makes no sense.
+Così siamo giunti ai veri argomenti avanzati. Vorremmo che un quantificatore come `pattern:+` non operasse backtracking, perché delle volte il backtracking non ha senso.
-The pattern to take as many repetitions of `pattern:\w` as possible without backtracking is: `pattern:(?=(\w+))\1`. Of course, we could take another pattern instead of `pattern:\w`.
+Il pattern per prendere quante più ripetizioni di `pattern:\w` possibili senza backtracking è: `pattern:(?=(\w+))\1`. Naturalmente, possiamo prendere un altro pattern al posto di `pattern:\w`.
-That may seem odd, but it's actually a very simple transform.
+Questo può sembrare strano, ma in realtà è una trasformazione molto semplice.
-Let's decipher it:
+Decifriamo:
-- Lookahead `pattern:?=` looks forward for the longest word `pattern:\w+` starting at the current position.
-- The contents of parentheses with `pattern:?=...` isn't memorized by the engine, so wrap `pattern:\w+` into parentheses. Then the engine will memorize their contents
-- ...And allow us to reference it in the pattern as `pattern:\1`.
+- Lookahead `pattern:?=` cerca in avanti la parola più lunga `pattern:\w+` che inizia dalla posizione corrente.
+- Il contenuto delle parentesi con `pattern:?=...` non è memorizzato dal motore, quindi si racchiude `pattern:\w+` tra le parentesi. In seguito il motore memorizzerà il loro contenuto.
+- ...E ci permetterà di riferirlo nel pattern come `pattern:\1`.
-That is: we look ahead - and if there's a word `pattern:\w+`, then match it as `pattern:\1`.
+Cioè: noi guardiamo in avanti - e se c'è una parola `pattern:\w+`, la si fa corrispondere a `pattern:\1`.
-Why? That's because the lookahead finds a word `pattern:\w+` as a whole and we capture it into the pattern with `pattern:\1`. So we essentially implemented a possessive plus `pattern:+` quantifier. It captures only the whole word `pattern:\w+`, not a part of it.
+Perché? Perché la trasformazione lookahead trova una parola per intero `pattern:\w+` e noi la catturiamo nel pattern con `pattern:\1`. Quindi, essenzialmente, implementiamo un quantificatore (con segno più) possessivo `pattern:+`. Esso cattura solo la parola intera `pattern:\w+`, non una sua parte.
-For instance, in the word `subject:JavaScript` it may not only match `match:Java`, but leave out `match:Script` to match the rest of the pattern.
+Per esempio, nella parola `subject:JavaScript` potrebbe non soltanto trovare la corrispondenza `match:Java`, ma lasciare fuori `match:Script` per trovare corrispondenze col resto del pattern.
-Here's the comparison of two patterns:
+Ecco i due pattern a confronto:
```js run
alert( "JavaScript".match(/\w+Script/)); // JavaScript
alert( "JavaScript".match(/(?=(\w+))\1Script/)); // null
```
-1. In the first variant `pattern:\w+` first captures the whole word `subject:JavaScript` but then `pattern:+` backtracks character by character, to try to match the rest of the pattern, until it finally succeeds (when `pattern:\w+` matches `match:Java`).
-2. In the second variant `pattern:(?=(\w+))` looks ahead and finds the word `subject:JavaScript`, that is included into the pattern as a whole by `pattern:\1`, so there remains no way to find `subject:Script` after it.
+1. Nella prima variante `pattern:\w+` inizialmente cattura la parola intera `subject:JavaScript` ma poi `pattern:+` usa il backtrack carattere dopo carattere nel tentativo di trovare il resto del pattern, finché alla fine riesce (quando `pattern:\w+` trova `match:Java`).
+2. Nella seconda variante `pattern:(?=(\w+))` guarda in avanti e trova la parola `subject:JavaScript`, che è inclusa nel pattern, per intero, da `pattern:\1`, così non resta alcun modo per trovare `subject:Script` dopo di essa.
-We can put a more complex regular expression into `pattern:(?=(\w+))\1` instead of `pattern:\w`, when we need to forbid backtracking for `pattern:+` after it.
+Possiamo porre un'espressione regolare più complicata in `pattern:(?=(\w+))\1` al posto di `pattern:\w`, quando abbiamo bisogno di impedire il backtracking per `pattern:\+` dopo di questa.
-```smart
-There's more about the relation between possessive quantifiers and lookahead in articles [Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead](http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead) and [Mimicking Atomic Groups](http://blog.stevenlevithan.com/archives/mimic-atomic-groups).
-```
+---
-Let's rewrite the first example using lookahead to prevent backtracking:
+C'è altro materiale sulla relazione tra quantificatori possessivi e lookahead negli articoli [Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead](http://instanceof.me/post/52245507631/regex-emulate-atomic-grouping-with-lookahead) e [Mimicking Atomic Groups](http://blog.stevenlevithan.com/archives/mimic-atomic-groups).
+
+---
+
+Riscriviamo il primo esempio usando un'espressione lookahead per prevenire il backtracking
```js run
let regexp = /^((?=(\w+))\2\s?)*$/;
-alert( regexp.test("A good string") ); // true
+alert( regexp.test("A good string") ); // vero
let str = "An input string that takes a long time or even makes this regex hang!";
-alert( regexp.test(str) ); // false, works and fast!
+alert( regexp.test(str) ); // falso, funziona ed è veloce!
```
-Here `pattern:\2` is used instead of `pattern:\1`, because there are additional outer parentheses. To avoid messing up with the numbers, we can give the parentheses a name, e.g. `pattern:(?Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: