Diciamo che ho un elenco di espressioni regolari (letto da una fonte esterna - file, database ecc.). Voglio controllare a quale di queste espressioni regolari corrisponde una stringa.Combinare più espressioni regolari in un automa
Posso creare un'iterazione attraverso tutte queste espressioni regolari e farle corrispondere, ma l'elenco potrebbe essere enorme e questa è un'operazione critica.
Posso combinare tutte queste espressioni regolari in una (con | tra di esse), ma il problema è che posso identificare solo la prima espressione regolare con corrispondenza, non tutte.
Un'altra idea potrebbe essere quella di creare un automa per tutte queste espressioni regolari e contrassegnare gli stati finali con, diciamo, gli indici dell'espressione regolare corrispondente. Stavo guardando http://cs.au.dk/~amoeller/automaton/, una libreria che sembra in grado di funzionare con espressioni regolari e automa, ma non è sicuro che possa essere estesa per risolvere il mio problema.
Avete altre idee?
per chiarire alcuni commenti, ho aggiunto un esempio di codice:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTest {
public static void main(String[] args) {
Pattern p = Pattern.compile("(a(?:b|c)a)|((?:a|b)ba)|(ab(?:a|c))");
Matcher m = p.matcher("aba");
System.out.println(m.matches());
System.out.println(m.groupCount());
for (int i = 0, n = m.groupCount(); i < n; i++) {
System.out.println(m.group(i));
}
}
}
sarà stampare
true
3
aba
aba
null
Come si può vedere solo il primo gruppo è abbinato e non vedo un modo per abbinare gli altri due.
Altri risultati - Utilizzando la libreria dell'automa sopra, il problema si riduce a quanto segue: se si concatenano due o più automi, come è possibile identificare per uno stato finale a quale degli automi originali è corrispondente?
Avete considerato di aggiungere gruppi denominati a ciascuna delle espressioni | ed? Puoi controllare quali corrispondono allora. –
Questi sembrano le opzioni disponibili per Java. In Perl, sarebbe più facile. Puoi semplicemente alternare tutte le espressioni e alla fine di ogni espressione (chiamata 'X') aggiungi per esempio' (? {$ Abbinato {X} = 1}) (?!) '. Che contrassegna l'espressione 'X' come abbinata, e quindi fallisce la corrispondenza, permettendo anche ad altre espressioni di coincidere. (Per ottimizzarlo puoi anche inserire ogni espressione in un gruppo di acquisizione atomico.) – Qtax
@ Michael: Sì, ho considerato anche questo. Il problema è che regexp in Java corrisponde solo al primo gruppo (denominato o senza nome). –