Открыть меню
Открыть персональное меню
Вы не представились системе
Your IP address will be publicly visible if you make any edits.

Регулярные выражения в АппОптима: различия между версиями

Материал из Документация АппОптима
(Новая страница: «Регулярные выражения очень эффективны, если вы хотите найти или извлечь определенный ша...»)
 
Нет описания правки
 
(не показана 1 промежуточная версия этого же участника)
Строка 3: Строка 3:
Регулярные выражения также часто неправильно понимаются. Небольшое регулярное выражение может легко потреблять много вычислительной мощности при неправильном использовании. В качестве примера рассмотрим это регулярное выражение <code>(.*)+b</code>. Это выражение может не выглядеть опасным, но если вы выполните его для большей строки, которая не содержит <code>b</code>, это выражение приведет к циклу, который будет длиться более 10 секунд.
Регулярные выражения также часто неправильно понимаются. Небольшое регулярное выражение может легко потреблять много вычислительной мощности при неправильном использовании. В качестве примера рассмотрим это регулярное выражение <code>(.*)+b</code>. Это выражение может не выглядеть опасным, но если вы выполните его для большей строки, которая не содержит <code>b</code>, это выражение приведет к циклу, который будет длиться более 10 секунд.


По этим причинам мы ограничили регулярные выражения в Ключ-АСТРОМ. Однако почти во всех случаях это не ограничит вашу функциональность. Это может заставить вас узнать немного больше о регулярных выражениях.
По этим причинам мы ограничили регулярные выражения в АппОптима. Однако почти во всех случаях это не ограничит вашу функциональность. Это может заставить вас узнать немного больше о регулярных выражениях.


== Ограничения ==
== Ограничения ==
Ознакомьтесь с приведенными ниже ограничениями, чтобы понять, как использовать регулярные выражения в контексте Ключ-АСТРОМ.
Ознакомьтесь с приведенными ниже ограничениями, чтобы понять, как использовать регулярные выражения в контексте АппОптима.


=== Количественные или повторяющиеся группы не допускаются ===
=== Количественные или повторяющиеся группы не допускаются ===
Строка 18: Строка 18:


=== Greedy matches в группах против possessive matches ===
=== Greedy matches в группах против possessive matches ===
Ключ-АСТРОМ не допускает '''Greedy matches''' в группах. Вместо этого используйте '''lazy''' или '''possessive matches'''.
АппОптима не допускает '''Greedy matches''' в группах. Вместо этого используйте '''lazy''' или '''possessive matches'''.


Прототипом регулярного выражения является термин <code>.*</code>. '''Greedy match''' определяется как '''Совпадения от нуля до неограниченного количества раз, столько раз, сколько возможно, возвращая обратно по мере необходимости (Greedy)'''. Проблема здесь в '''''столько раз''''' и '''''возвращении обратно'''''. Люди обычно используют это для сопоставления чего-либо, пока не будет выполнено граничное условие. Рассмотрим следующее сопоставление регулярного выражения:
Прототипом регулярного выражения является термин <code>.*</code>. '''Greedy match''' определяется как '''Совпадения от нуля до неограниченного количества раз, столько раз, сколько возможно, возвращая обратно по мере необходимости (Greedy)'''. Проблема здесь в '''''столько раз''''' и '''''возвращении обратно'''''. Люди обычно используют это для сопоставления чего-либо, пока не будет выполнено граничное условие. Рассмотрим следующее сопоставление регулярного выражения:
Строка 39: Строка 39:


=== Группы не допускаются для простых матчей. ===
=== Группы не допускаются для простых матчей. ===
Группы захвата в регулярных выражениях используются для извлечения информации. Иногда эта концепция неправильно используется для простых совпадений поиска. Поскольку это только добавляет накладные расходы и не является необходимым, Ключ-АСТРОМ не допускает этого. В большинстве случаев можно использовать '''''[https://www.regular-expressions.info/atomic.html атомарные группы]''''' вместо этого. Для обеспечения высокой производительности продукта в определениях регулярных выражений могут применяться дополнительные ограничения группировки, например, '''''[[Настройка наименования запросов|в правилах именования запросов]]''''' .
Группы захвата в регулярных выражениях используются для извлечения информации. Иногда эта концепция неправильно используется для простых совпадений поиска. Поскольку это только добавляет накладные расходы и не является необходимым, АппОптима не допускает этого. В большинстве случаев можно использовать '''''[https://www.regular-expressions.info/atomic.html атомарные группы]''''' вместо этого. Для обеспечения высокой производительности продукта в определениях регулярных выражений могут применяться дополнительные ограничения группировки, например, '''''[[Настройка наименования запросов|в правилах именования запросов]]''''' .


Ключ-АСТРОМ допускает только одну группу захвата в местах, где вам нужно извлечь значение. Логика здесь такова: если регулярное выражение содержит группу, Ключ-АСТРОМ будет ее использовать. В противном случае для извлечения используется полное совпадение.
АппОптима допускает только одну группу захвата в местах, где вам нужно извлечь значение. Логика здесь такова: если регулярное выражение содержит группу, АппОптима будет ее использовать. В противном случае для извлечения используется полное совпадение.


Это означает, что вам вообще не нужно использовать группы захвата. В большинстве сценариев извлечения достаточно просто определить, что вы хотите получить. В случае извлечения следующее регулярное выражение захватит значение — группа захвата не нужна.
Это означает, что вам вообще не нужно использовать группы захвата. В большинстве сценариев извлечения достаточно просто определить, что вы хотите получить. В случае извлечения следующее регулярное выражение захватит значение — группа захвата не нужна.
Строка 53: Строка 53:
Это позволит захватить данные <code>Windows NT 10.0</code>, и в группе захвата нет необходимости.
Это позволит захватить данные <code>Windows NT 10.0</code>, и в группе захвата нет необходимости.


=== Ключ-АСТРОМ не допускает обратных ссылок ===
=== АппОптима не допускает обратных ссылок ===
Обратные ссылки часто используются для решения иерархических или рекурсивных соответствий, оба из которых с большой вероятностью могут оказаться очень затратными и не нужны в Ключ-АСТРОМ.
Обратные ссылки часто используются для решения иерархических или рекурсивных соответствий, оба из которых с большой вероятностью могут оказаться очень затратными и не нужны в АппОптима.


== Другие распространенные заблуждения ==
== Другие распространенные заблуждения ==
Строка 63: Строка 63:
<code>Value: something. key: value; something else</code>
<code>Value: something. key: value; something else</code>


Это соответствует полной строке, а не только тому, что нужно. Это основано на недоразумении, что заданное регулярное выражение всегда будет соответствовать полному тексту, тогда как обычно оно используется для поиска подстроки. В Ключ-АСТРОМ условия регулярного выражения обычно ищут шаблон и не сопоставляют принудительно весь ввод. Начальные и конечные (<code>.*</code>) соответствия не нужны, поэтому, пожалуйста, не используйте их.
Это соответствует полной строке, а не только тому, что нужно. Это основано на недоразумении, что заданное регулярное выражение всегда будет соответствовать полному тексту, тогда как обычно оно используется для поиска подстроки. В АппОптима условия регулярного выражения обычно ищут шаблон и не сопоставляют принудительно весь ввод. Начальные и конечные (<code>.*</code>) соответствия не нужны, поэтому, пожалуйста, не используйте их.

Текущая версия от 12:06, 22 декабря 2024

Регулярные выражения очень эффективны, если вы хотите найти или извлечь определенный шаблон в строке. Однако с большой силой приходит большая ответственность. Регулярные выражения могут привести к неожиданным результатам (lazy vs greedy matching) и они могут быстро стать ресурсоемкими (catastrophic backtracking и repeated capture groups).

Регулярные выражения также часто неправильно понимаются. Небольшое регулярное выражение может легко потреблять много вычислительной мощности при неправильном использовании. В качестве примера рассмотрим это регулярное выражение (.*)+b. Это выражение может не выглядеть опасным, но если вы выполните его для большей строки, которая не содержит b, это выражение приведет к циклу, который будет длиться более 10 секунд.

По этим причинам мы ограничили регулярные выражения в АппОптима. Однако почти во всех случаях это не ограничит вашу функциональность. Это может заставить вас узнать немного больше о регулярных выражениях.

Ограничения

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

Количественные или повторяющиеся группы не допускаются

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

Regex: (a+)+b

Value:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

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

Greedy matches в группах против possessive matches

АппОптима не допускает Greedy matches в группах. Вместо этого используйте lazy или possessive matches.

Прототипом регулярного выражения является термин .*. Greedy match определяется как Совпадения от нуля до неограниченного количества раз, столько раз, сколько возможно, возвращая обратно по мере необходимости (Greedy). Проблема здесь в столько раз и возвращении обратно. Люди обычно используют это для сопоставления чего-либо, пока не будет выполнено граничное условие. Рассмотрим следующее сопоставление регулярного выражения:

Regex: key: (.*);

Value: something. key: value; something else

Механизм регулярных выражений сначала ищет key: и затем greedy сопоставляет группу (.*) до конца строки . Затем он проверяет, есть ли ; после этого совпадения ; чего никогда не будет. Затем ему приходится возвращаться по одному символу за раз. Каждый раз он сначала проверяет, совпадает ли группа каждый раз, пока не найдет ;. В качестве небольшой детали, ему также придется каждый раз запоминать новое значение для группы; так как это группа захвата. Все это очень ресурсоемко и неэффективно; и, что более важно, сложность возрастает с длиной строки, которую нужно сопоставить.

Лучший способ сделать это следующий:

Regex: key: ([^;]*+)

Value: something. key: value; something else

Это соответствие будет соответствовать до тех пор, пока не будет найдено ; после key: . Плюс также превращает это в possessive match, определяемое как: Совпадает от нуля до неограниченного количества раз, столько раз, сколько возможно, без возврата (possessive). Ключевым моментом здесь является то, что он не возвращается. Другими словами, как только что-то совпало, движок не будет пересматривать и не будет смотреть назад, а только вперед. Именно поэтому нам нужно уточнить соответствие от «все» (.) до «все, но не ;». Нам нужно сказать ему, чтобы он соответствовал всему, но не ;.

Если сравнить первое регулярное выражение против второго в отладчике регулярных выражений (перейдите по двум ссылкам) вы также заметите, что первый занимает 42 шага, а второй — 9! Вот почему мы рекомендуем вам использовать possessive matches в целом.

Группы не допускаются для простых матчей.

Группы захвата в регулярных выражениях используются для извлечения информации. Иногда эта концепция неправильно используется для простых совпадений поиска. Поскольку это только добавляет накладные расходы и не является необходимым, АппОптима не допускает этого. В большинстве случаев можно использовать атомарные группы вместо этого. Для обеспечения высокой производительности продукта в определениях регулярных выражений могут применяться дополнительные ограничения группировки, например, в правилах именования запросов .

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

Это означает, что вам вообще не нужно использовать группы захвата. В большинстве сценариев извлечения достаточно просто определить, что вы хотите получить. В случае извлечения следующее регулярное выражение захватит значение — группа захвата не нужна.

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

Regex: Windows NT[^)]+

Value: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0 Safari/537.36

Это позволит захватить данные Windows NT 10.0, и в группе захвата нет необходимости.

АппОптима не допускает обратных ссылок

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

Другие распространенные заблуждения

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

Regex: .*key: [^;]*+.*

Value: something. key: value; something else

Это соответствует полной строке, а не только тому, что нужно. Это основано на недоразумении, что заданное регулярное выражение всегда будет соответствовать полному тексту, тогда как обычно оно используется для поиска подстроки. В АппОптима условия регулярного выражения обычно ищут шаблон и не сопоставляют принудительно весь ввод. Начальные и конечные (.*) соответствия не нужны, поэтому, пожалуйста, не используйте их.