Можно ли сделать это регулярное выражение эффективным для памяти? - PullRequest
0 голосов
/ 29 апреля 2020

Я получаю xml как простой неформатированный текстовый шарик. Я должен сделать некоторые замены, и я использую регулярное выражение найти и заменить. Например:

<MeasureValue><Text value="StartCalibration" /></MeasureValue>

должен быть преобразован в

<MeasureValue type="Text" value="StartCalibration"/>

Регулярное выражение, которое я написал, было

<MeasureValue><((\w*)\s+value="(.*?)".*?)></MeasureValue>

И заменяющая часть была:

<MeasureValue type="$2" value="$3"/>

Здесь ссылка , показывающая то же самое.

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

РЕДАКТИРОВАТЬ: Это часть сценария для Logsta sh от Elasticsearch. Согласно документации, Elasticsearch использует Apache Lucene для анализа регулярных выражений. Не уверен, поможет ли это.

1 Ответ

1 голос
/ 29 апреля 2020

Как правило, специфика положительно коррелирует с эффективностью в регулярных выражениях. Итак, знает ваши данные и строит что-то для хирургического соответствия.

Чем больше спецификаций c вы строите свое регулярное выражение, как буквально записываете шаблон (и обычно заканчиваете уродом) регулярное выражение), тем меньше ресурсов он будет использовать из-за меньшего количества «возможностей», которые он может сопоставить в ваших данных.

Чтобы быть более точным, представьте, что мы пытаемся сопоставить строку

2014-08-26 app[web.1]: 50.0.134.125

Такие подходы, как

(.*) (.*) (.*)

, делают его слишком открытым и склонным к совпадению со МНОГИМИ различными образцами и комбинациями, и, таким образом, для обработки его бесконечных возможностей требуется МНОГО. отметьте здесь https://regex101.com/r/GvmPOC/1

С другой стороны, вы могли бы потратить немного больше времени на создание более сложного выражения, такого как:

^[0-9]{4}\-[0-9]{2}-[0-9]{2} app\[[a-zA-Z0-9.]+\]\: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$`

и я согласен, это это ужасно, но гораздо точнее. Это не будет тратить ваши драгоценные ресурсы на поиск ненужных вещей. отметьте здесь https://regex101.com/r/quz7fo/1

Еще одна вещь, которую следует иметь в виду: операторы, такие как * или +, выполняют операцию сканирования, которая в зависимости от размера вашей строки может занять некоторое время Также, когда это возможно, указание якорей ^$ также помогает сценарию не пытаться найти слишком много совпадений в одной и той же строке.


Внося это в вашу реальность ...

Если нам нужно использовать регулярное выражение.

Вопрос на миллион долларов: как мы можем превратить ваше регулярное выражение во что-то более точное?

Поскольку там нет ограничений на длину имени тега в XML ... нет способа сделать его полностью конкретным c: (

  • Мы можем попытаться указать, какие символы сопоставлять и избегать . и \w. Поэтому желательно заменить его на что-то более похожее на a-zA-Z. Также использование отрицательных классов [^] поможет сузить диапазон возможностей.

  • Избегайте * и ? и попробуйте ввести квантификатор {} (хотя я не знаю ваших данных для принятия этого решения). Как я уже говорил выше, в * нет ограничений 1090 * за это.

  • Я не совсем понял фу Значение ? в вашем коде, поэтому удаление его - это менее сложная обработка.

Завершено чем-то вроде

<(([a-zA-Z]+) value="([^"]*)"[^<>]*)>

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

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

Если есть небольшая возможность использовать xml парсер было бы предпочтительнее.

https://softwareengineering.stackexchange.com/questions/113237/when-you-should-not-use-regular-expressions

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

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