Если вы используете Perl или какой-либо механизм PCRE (например, функции PHP preg_
), вы можете ссылаться на предыдущие группы в шаблоне, например:
/(a)(b)|(?1)|(?2)/
Основная цель этой функции — поддержка рекурсии, но ее также можно использовать для повторного использования шаблонов.
Обратите внимание, что в этом случае вы не можете обойти захват a
и b
в первом чередовании, что влечет за собой некоторые (возможно) ненужные накладные расходы. Чтобы избежать этого, вы можете определить группы внутри условного оператора, который никогда не выполняется. Канонический способ сделать это - использовать группу (?(DEFINE)...)
(которая проверяет, соответствует ли именованная группа DEFINE
чему-либо, но, конечно, эта группа не существует):
/(?(DEFINE)(a)(b))(?1)(?2)|(?1)|(?2)/
Если ваш движок не поддерживает это (EDIT: поскольку вы используете Java, эта функция не поддерживается), лучшее, что вы можете получить в одном шаблоне, действительно
ab?|b
В качестве альтернативы вы можете создать версию ab|a|b
вручную путем объединения/форматирования строк, например:
String a = "a";
String b = "b";
String pattern = a + b + "|" + a + "|" + b;
Это также позволяет избежать дублирования. Или вы можете использовать 3 отдельных шаблона ab
, a
и b
для строки темы (где первый снова является конкатенацией двух последних).
person
Martin Ender
schedule
25.04.2013
a
иb
. - person sp00m   schedule 25.04.2013(ab?)|(a?b)
? Не кажется проще, и анализ DFA, вероятно, построит такое же дерево синтаксического анализа. - person leppie   schedule 25.04.2013