Когда стоит использовать RegEx в Java? - PullRequest
4 голосов
/ 08 ноября 2010

Я пишу небольшое приложение, которое читает некоторые входные данные и делает что-то на основе этих входных данных.

В настоящее время я ищу строку, которая заканчивается, скажем, "магией", я бы использовал String'sendsWith метод.Любой, кто читает мой код, понимает, что происходит.

Еще один способ сделать это - создать шаблон и попытаться сопоставить строку, заканчивающуюся «магией».Это также ясно, но я лично считаю, что это излишнее, потому что шаблон, который я ищу, совсем не сложен.

Когда вы думаете, стоит ли использовать RegEx Java?Если это сложность, как бы вы лично определили, что достаточно сложно?

Кроме того, бывают ли случаи, когда использование шаблонов на самом деле быстрее, чем манипуляции со строками?используя Java 6.

Ответы [ 11 ]

10 голосов
/ 08 ноября 2010

В основном: если есть операция без регулярных выражений, которая делает то, что вы хотите за один шаг, всегда идите на это.

Это не столько вопрос производительности, сколько) удобочитаемость и б) безопасность во время компиляции.Специализированные версии без регулярных выражений обычно намного легче читать, чем регулярные выражения.И опечатка в одном из этих специализированных методов не будет компилироваться, в то время как опечатка в Regex с треском провалится во время выполнения.

Сравнение решений на основе Regex с решениями не-Regex

String s = "Magic_Carpet_Ride";

s.startsWith("Magic");   // non-regex
s.matches("Magic.*");    // regex

s.contains("Carpet");    // non-regex
s.matches(".*Carpet.*"); // regex

s.endsWith("Ride");      // non-regex
s.matches(".*Ride");     // regex

Во всех этих случаях это просто: используйте версию без регулярных выражений.

Но когда все становится немного сложнее, это зависит.Я думаю, что я все еще буду придерживаться не-регулярных выражений в следующем случае, но многие не будут:

// Test whether a string ends with "magic" in any case,
// followed by optional white space
s.toLowerCase().trim().endsWith("magic"); // non-regex, 3 calls
s.matches(".*(?i:magic)\\s*");            // regex, 1 call, but ugly

И в ответ на RegexesCanCertainlyBeEasierToReadThanMultipleFunctionCallsToDoTheSameThing:

Я все ещеЯ думаю, что версия без регулярных выражений более читабельна, но я бы написал так:

s.toLowerCase()
 .trim()
 .endsWith("magic");

Разница не так?

3 голосов
/ 08 ноября 2010

Вы бы использовали Regex, когда обычных манипуляций над классом String недостаточно для элегантного получения того, что вам нужно от String.

Хороший индикатор того, что это тот случай, когда вы начинаете разделение, затем разделяете эти результаты, а затем разделяете эти результаты.Код становится громоздким.Две строки кода Pattern / Regex могут очистить это, аккуратно завернутый в метод, который является модульным тестированием ....

2 голосов
/ 08 ноября 2010

Все, что можно сделать с помощью регулярных выражений, также можно кодировать вручную.

Используйте регулярное выражение, если:

  1. Выполнение этого вручную потребует больше усилий без особой пользы.
  2. Вы можете легко придумать регулярное выражение для вашей задачи.

Не использовать регулярное выражение, если:

  1. В противном случае это очень легко сделать, как в вашем примере.
  2. Строка, которую вы анализируете, не подходит для регулярных выражений. (на этот вопрос принято ссылаться )
1 голос
/ 08 ноября 2010

Я думаю, вам лучше всего использовать endsWith.Если ваши требования не изменятся, это будет проще и легче понять.Может и быстрее работать"с последующим пробелом и затем одним словом, таким как" ... волшебная ложка ", но не" ... волшебная ложка для супа ", тогда я думаю, что RegEx будет лучшим способом.

0 голосов
/ 08 ноября 2010

Если вы знакомы с тем, как работает regexp, вы скоро обнаружите, что многие проблемы легко решаются с помощью regexp.

Лично я смотрю на использование операций Java String, если это легко, но если вы начинаетеразбивая строки и выполняя их подстроку, я начинаю думать в регулярных выражениях.

И снова, если вы используете регулярные выражения, зачем останавливаться на строках.Сконфигурировав свое регулярное выражение, вы можете легко читать целые файлы в одном регулярном выражении (Pattern.DOTALL в качестве параметра для Pattern.compile, и ваше регулярное выражение не заканчивается на новых строках).Я бы совмещал это с методами Apache Commons IOUtils.toString (), и у вас есть что-то очень мощное, чтобы делать быстрые вещи.

Я бы даже вывел регулярное выражение для анализа некоторого xml при необходимости.(Например, в модульном тесте, где я хочу проверить наличие некоторых элементов в xml).

Например, из какого-то моего модульного теста:

Pattern pattern = Pattern.compile(
                "<Monitor caption=\"(.+?)\".*?category=\"(.+?)\".*?>"
                + ".*?<Summary.*?>.+?</Summary>"
                + ".*?<Configuration.*?>(.+?)</Configuration>"
                + ".*?<CfgData.*?>(.+?)</CfgData>", Pattern.DOTALL);

, который будетсопоставьте все сегменты в этом xml и выделите некоторые сегменты, для которых я хочу выполнить некоторое совпадение.

0 голосов
/ 08 ноября 2010

Я бы предложил использовать регулярное выражение, когда вы знаете формат ввода, но вы не обязательно уверены в значении (или возможных значениях) отформатированного ввода.

То, что я говорю, если у вас есть все входные данные, заканчивающиеся, в вашем случае, «магией», тогда String.endsWith() работает нормально (если вы знаете, что ваше возможное входное значение закончится «магическим»).

Если у вас есть формат, например формат сообщения RFC 5322 , нельзя однозначно сказать, что все адреса электронной почты могут заканчиваться .com, поэтому вы можете создать регулярное выражение, соответствующее RFC 5322стандарт для проверки.

В двух словах: если вы знаете структуру формата ваших входных данных, но не знаете точно, какие значения (или возможные значения) вы можете получить, используйте для проверки регулярные выражения.

0 голосов
/ 08 ноября 2010

Я бы никогда не использовал регулярные выражения в Java, если бы у меня был более простой способ сделать это, как в этом случае метод endsWith.Регулярные выражения в java настолько безобразны, насколько это возможно, вероятно, за единственным исключением метода match для String.

. Обычно избегание регулярных выражений делает ваше ядро ​​более читабельным и более простым для других программистов.Наоборот, сложные регулярные выражения могут запутать даже самых опытных хакеров.

Что касается проблем с производительностью: просто профиль.Особенно в Яве.

0 голосов
/ 08 ноября 2010

Если это так же просто, как заканчивается с, начинается с или содержит, то вы должны использовать эти функции.Если вы обрабатываете более «сложные» строки и хотите извлечь информацию из этих строк, то можно использовать регулярные выражения / соответствия.

Если у вас есть что-то вроде «commandToRetrieve someNumericArgs someOptionalArgs», то регулярное выражение упростит вашу задачумного :) 1003 *

0 голосов
/ 08 ноября 2010

Если базовое окончание строки всегда одинаковое, например, с «магией», то лучше использовать конец с.

Однако, если у вас есть строка, которая имеет одинаковую базу, но может иметь несколько значений, например:

<string> <number> <string> <string> <number>

где строки и числа могут быть любыми, лучше использовать RegEx.

Ваши строки всегда заканчиваются строкой, но вы не знаете, что это за строка.

0 голосов
/ 08 ноября 2010

Есть такая поговорка:

Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать регулярные выражения».Теперь у них две проблемы .( ссылка ).

Для простого теста я бы поступил точно так же, как вы.Если вы обнаружите, что все становится сложнее, то я бы рассмотрел Регулярные выражения, только если нет другого пути.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...