Код фактически находится на Scala (Spark / Scala), но библиотека scala.util.matching.Regex, согласно документации, делегирует java.util.regex.
Код, по сути, считывает множество регулярных выражений из файла конфигурации, а затем сопоставляет их с журналами, подаваемыми в приложение Spark / Scala. Все работало нормально, пока я не добавил регулярное выражение для извлечения строк, разделенных вкладками, где вкладка была сглажена до "# 011" (с помощью rsyslog). Поскольку в строках могут быть пробелы, мое регулярное выражение выглядит так: (.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)#011(.+?)
В тот момент, когда я добавляю это регулярное выражение в список, приложению требуется вечность, чтобы завершить обработку журналов. Чтобы дать вам представление о величине задержки, типичный пакет из миллиона строк занимает менее 5 секунд для сопоставления / извлечения в моем кластере Spark. Если я добавлю выражение выше, партия займет час!
В моем коде я пробовал несколько способов сопоставить регулярное выражение:
if ( (regex findFirstIn log).nonEmpty ) { do something }
val allGroups = regex.findAllIn(log).matchData.toList if (allGroups.nonEmpty) { do something }
if (regex.pattern.matcher(log).matches()){do something}
Все три страдают от низкой производительности, когда упомянутое выше регулярное выражение было добавлено в список регулярных выражений. Любые предложения по улучшению производительности регулярного выражения или изменению самого регулярного выражения?
Вопрос / ответ, помеченный как дубликат, содержит ссылку что мне трудно уследить. Было бы легче следить за текстом, если бы упомянутое программное обеспечение, regexbuddy, было бесплатным или, по крайней мере, работало на Mac.
Я пробовал отрицательный просмотр вперед, но не могу понять, как отрицать строку. Вместо /(.+?)#011/
, что-то вроде /([^#011]+)/
, но в нем просто написано отрицание "#", "0" или "1". Как мне отрицать "# 011"? Даже после этого я не уверен, решит ли отрицание мою проблему с производительностью.
^
и$
)? Кроме того, есть ли еще какие-нибудь#
символы, кроме тех, что на сглаженных TAB? Может быть, вы могли бы использовать([^#]++)
вместо(.+?)
. - person Alan Moore   schedule 15.05.2015(?:(?:(?!#011).)++#011){34}(?:.+?)
- person Bart Kiers   schedule 15.05.2015