В чем важность Pattern.compile()
метода?
Почему мне нужно скомпилировать строку регулярного выражения перед получением Matcher
объекта?
Например :
String regex = "((\\S+)\\s*some\\s*";
Pattern pattern = Pattern.compile(regex); // why do I need to compile
Matcher matcher = pattern.matcher(text);
new Pattern(regex)
вместо статической функции компиляции. комментарий marcolopes на месте.Ответы:
compile()
Метод всегда вызывается в какой - то момент; это единственный способ создать объект Pattern. Итак, вопрос в том, почему вы должны называть это явно ? Одна из причин заключается в том, что вам нужна ссылка на объект Matcher, чтобы вы могли использовать его методы, например,group(int)
для получения содержимого групп захвата. Единственный способ получить объект Matcher - использовать метод объекта Patternmatcher()
, а единственный способ получить объект Pattern - использовать этотcompile()
метод. Затем естьfind()
метод, который, в отличие от негоmatches()
, не дублируется в классах String или Pattern.Другая причина - избегать создания одного и того же объекта Pattern снова и снова. Каждый раз, когда вы используете один из методов на основе регулярных выражений в String (или статический
matches()
метод в Pattern), он создает новый Pattern и новый Matcher. Итак, этот фрагмент кода:... в точности эквивалентно этому:
Очевидно, это делает много ненужной работы. Фактически, на компиляцию регулярного выражения и создание экземпляра объекта Pattern может уйти больше времени, чем на фактическое сопоставление. Поэтому обычно имеет смысл вытащить этот шаг из цикла. Вы также можете создать Matcher заранее, хотя они и далеко не такие дорогие:
Если вы знакомы с регулярными выражениями .NET, вам может быть интересно,
compile()
связан ли метод Java сRegexOptions.Compiled
модификатором .NET ; ответ - нет.Pattern.compile()
Метод Java просто эквивалентен конструктору Regex в .NET. Когда вы указываетеCompiled
опцию:... он компилирует регулярное выражение непосредственно в байтовый код CIL, что позволяет ему работать намного быстрее, но со значительными затратами на предварительную обработку и использование памяти - думайте об этом как о стероидах для регулярных выражений. Java не имеет эквивалента; нет никакой разницы между шаблоном, который создается за кулисами,
String#matches(String)
и шаблоном, который вы создаете явноPattern#compile(String)
.(РЕДАКТИРОВАТЬ: я изначально сказал, что все объекты .NET Regex кэшируются, что неверно. Начиная с .NET 2.0, автоматическое кеширование происходит только со статическими методами, например
Regex.Matches()
, а не при прямом вызове конструктора Regex. Ref )источник
reset
использовать объект Matcher, который когда-либо использовался только одним потоком за раз, чтобы уменьшить выделение.Компиляция анализирует регулярное выражение и строит представление в памяти . Накладные расходы на компиляцию значительны по сравнению с сопоставлением. Если вы используете шаблон неоднократно, он повысит производительность для кеширования скомпилированного шаблона.
источник
Когда вы компилируете,
Pattern
Java выполняет некоторые вычисления, чтобыString
ускорить поиск совпадений в s. (Строит представление регулярного выражения в памяти)Если вы собираетесь повторно использовать
Pattern
несколько раз, вы увидите значительное увеличение производительности по сравнению с созданием новогоPattern
каждый раз.В случае использования Pattern только один раз, этап компиляции кажется лишней строкой кода, но на самом деле он может быть очень полезным в общем случае.
источник
Matcher matched = Pattern.compile(regex).matcher(text);
. У этого есть преимущества по сравнению с введением одного метода: аргументы эффективно именуются, и очевидно, как исключить из нихPattern
для повышения производительности (или разделить между методами).Это вопрос производительности и использования памяти, скомпилируйте и сохраните соблюдаемый шаблон, если вам нужно его много использовать. Типичное использование регулярного выражения - это проверенный пользовательский ввод (формат) , а также форматирование выходных данных для пользователей , в этих классах сохранение согласованного шаблона кажется вполне логичным, поскольку они обычно вызывали много.
Ниже представлен образец валидатора, которого действительно много называют :)
Как упоминал @Alan Moore, если в вашем коде есть многоразовое регулярное выражение (например, перед циклом), вы должны скомпилировать и сохранить шаблон для повторного использования.
источник
Pattern.compile()
позволяет многократно использовать регулярное выражение (это потокобезопасно). Прирост производительности может быть весьма значительным.Я сделал быстрый тест:
compileOnce был в 3–4 раза быстрее . Я думаю, это сильно зависит от самого регулярного выражения, но для часто используемого регулярного выражения я использую
static Pattern pattern = Pattern.compile(...)
источник
Предварительная компиляция регулярного выражения увеличивает скорость. Повторное использование Matcher дает вам еще одно небольшое ускорение. Если метод часто вызывается, скажем, вызывается в цикле, общая производительность, безусловно, возрастет.
источник
Подобно 'Pattern.compile', есть 'RECompiler.compile' [из com.sun.org.apache.regexp.internal], где:
1. скомпилированный код для шаблона [az] содержит 'az'
2. скомпилированный код для В шаблоне [0-9] есть '09'
3. в скомпилированном коде для шаблона [abc] есть 'aabbcc'.
Скомпилированный таким образом код - отличный способ обобщить несколько случаев. Таким образом, вместо того, чтобы иметь разные ситуации обработки кода 1,2 и 3. Проблема сводится к сравнению с ascii текущего и следующего элементов в скомпилированном коде, следовательно, пар. Таким образом,
a. все, что имеет ascii между a и z, находится между a и z
b. все, что имеет ascii между "a" и "a" определенно является "a"
источник
Класс Pattern - это точка входа в движок регулярных выражений. Вы можете использовать его через Pattern.matches () и Pattern.comiple (). # Разница между этими двумя. match () - для быстрой проверки, соответствует ли текст (String) заданному регулярному выражению comiple () - создает ссылку на Pattern. Таким образом, можно использовать несколько раз для сопоставления регулярного выражения с несколькими текстами.
Для справки:
источник