2009-08-09 14 views
15

Dopo aver letto un buon article sull'ottimizzazione delle espressioni regolari in java mi chiedevo quali sono gli altri buoni consigli per creare espressioni regolari veloci ed efficienti?Suggerimenti per l'ottimizzazione delle prestazioni Regex

+0

Vorrei citare [booleano Sequenza] (https://github.com/NaturalIntelligence/BooleanSequence) che attualmente supporta meno simboli di RE ma sono veloci, flessibili e ricchi di molte utili funzionalità. Puoi scrivere i tuoi corrispondenti per aggiungere più funzioni o renderle più veloci. Fanno anche l'ottimizzazione automatica e puoi vedere come vengono valutati usando grafici basati su JSON o JSON. –

risposta

7

Usa operatore qualsiasi (dot) con parsimonia, se è possibile farlo in qualsiasi altro modo, farlo, puntino sempre morderà ...

io non sono sicuro se PCRE è NFA e io sono solo familiarità con PCRE ma + e * di solito sono avidi di default, si abbineranno il più possibile per girare questo intorno all'uso +? e *? per abbinare il meno possibile, tenere a mente queste due clausole mentre scrivi la tua espressione regolare.

3

Sapere quando non utilizzare un'espressione regolare - a volte una soluzione codificata a mano è più efficiente e più comprensibile.

Esempio: si supponga di voler abbinare un numero intero che sia equamente divisibile per 3. È semplice progettare una macchina a stati finiti per realizzare questo, e quindi una regex corrispondente deve esistere, ma la sua scrittura non è così banale - e Oddio doverlo debugare!

+1

Sì ... ma è banale in alcuni sistemi numerici. :-P –

+9

vuoi dire questo: '(((0 | 3 | 6 | 9) | ((1 | 4 | 7) (0 | 3 | 6 | 9) * (2 | 5 | 8))) | (((2 | 5 | 8) | ((1 | 4 | 7) (0 | 3 | 6 | 9) * (1 | 4 | 7))) ((0 | 3 | 6 | 9) | ((2 | 5 | 8) (0 | 3 | 6 | 9) * (1 | 4 | 7))) * ((1 | 4 | 7) | ((2 | 5 | 8) (0 | 3 | 6 | 9) * (2 | 5 | 8))))) * '? (Sì, ho creato un DFA e poi GNFA quindi regex: p) –

+1

Usa un'implementazione veloce quando non hai backriver. https://swtch.com/~rsc/regexp/regexp1.html – clemens

27
  1. Utilizzare il gruppo non-cattura (?:pattern) quando è necessario ripetere un raggruppamento, ma non c'è bisogno di utilizzare il valore catturato che viene da un tradizionale (capturing) gruppo.
  2. Utilizzare la sottoespressione atomic group (o secondaria non di retromarcia) quando applicabile (?>pattern).
  3. Evita il catastrophic backtracking come l'epidemia progettando le tue espressioni regolari per terminare in anticipo per le non partite.

Ho creato un video che dimostra queste tecniche. Ho iniziato con la molto espressione regolare scritta male nell'articolo (x+x+)+y. E poi l'ho reso 3 milioni più veloce dopo una serie di ottimizzazioni, benchmark dopo ogni cambiamento. Il video è specifico per .NET, ma molte di queste cose si applicano alla maggior parte degli altri sapori regex così:

.NET Regex Lesson: #5: Optimization

Problemi correlati