Предположим, что у меня есть список регулярных выражений (чтение из внешнего источника - файла, базы данных и т. Д.). Я хочу проверить, какое из этих регулярных выражений соответствует строке.Объединение нескольких регулярных выражений в один автомат
Я могу создать итерацию через все эти регулярные выражения и сопоставить их, но список может быть огромным, и это критическая операция.
Я могу объединить все эти регулярные выражения в один (с ними между ними), но тогда проблема в том, что я могу идентифицировать только первое согласованное регулярное выражение, а не все.
Еще одна идея - создать автомат для всех этих регулярных выражений и пометить конечные состояния, скажем, индексами соответствующего регулярного выражения. Я смотрел на http://cs.au.dk/~amoeller/automaton/, библиотеку, которая кажется способной работать с регулярными выражениями и автоматом, но не уверена, что ее можно расширить, чтобы решить мою проблему.
Есть ли у вас какие-либо другие идеи?
Чтобы уточнить некоторые комментарии, я добавил пример кода:
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));
}
}
}
будет распечатать
true
3
aba
aba
null
Как вы можете видеть только первая группа соответствует, и я не вижу способ сопоставления двух других.
Другие выводы. Используя вышеприведенную библиотеку автомата, проблема сводится к следующему: если вы объединяете два или более автомата, как вы можете определить конечное состояние, к которому относится исходный автомат?
Рассматривали ли вы добавление названных групп в каждое из выражений? Вы могли бы проверить, какие из них совпадают. –
Эти звуки похожи на параметры, которые у вас есть для Java. В Perl это было бы проще. Вы можете просто чередовать все выражения, а в конце каждого выражения (называемого «X») добавить, например, '(? {$ Matchched {X} = 1}) (?!)'. Который маркирует выражение 'X' как совпадающее, а затем не соответствует совпадению, позволяя другим выражениям также соответствовать. (Чтобы его оптимизировать, вы можете также поместить каждое выражение в группу захвата атома.) – Qtax
@MichaelW: Да, я тоже это рассмотрел. Проблема в том, что regexp в Java соответствует только первой группе (названной или неназванной). –