questo è un vecchio post, ma a beneficio di coloro che trovando attraverso ricerche sul Web come ho fatto io, v'è un modulo Perl che fa questo, chiamato Regexp::Optimizer
, qui: http://search.cpan.org/~dankogai/Regexp-Optimizer-0.23/lib/Regexp/Optimizer.pm
Prende una espressione regolare come input, che può consistere solo dell'elenco di stringhe di input separate con |
e genera un'espressione regolare ottimale.
Ad esempio, questo Perl riga di comando:
perl -mRegexp::Optimizer -e "print Regexp::Optimizer->new->optimize(qr/1231|1233|1234|1236|1238|1247|1256|1258|1259/)"
genera questo output:
(?^:(?^:12(?:3[13468]|5[689]|47)))
(ammesso che abbiate installato Regex::Optimizer
), che corrisponde aspettativa del PO abbastanza bene.
Ecco un altro esempio:
perl -mRegexp::Optimizer -e "print Regexp::Optimizer->new->optimize(qr/314|324|334|3574|384/)"
E l'output:
(?^:(?^:3(?:[1238]|57)4))
Per confronto, una versione basata su trie ottimale sarebbe uscita 3(14|24|34|574|84)
. In uscita di cui sopra, è anche possibile cercare e sostituire (?:
e (?^:
con appena (
ed eliminare parentesi ridondanti, per ottenere questo:
3([1238]|57)4
fonte
2017-08-25 08:17:27
Non sarebbe la (breve) di output della funzione essere qualcosa come '12 [13 -9] \ {2 \} '? –
Ciò corrisponderebbe a cose che non sono nell'elenco, ad es. 1211 – Asmor
Il tuo motore regex lo fa già per te se concateni tutte le stringhe separate da un '|'. – arnaud576875