На жадібний проти не жадібний
Повторення у регулярному вираженні за замовчуванням є жадібним : вони намагаються зіставити якомога більше повторень, і коли це не працює, і їм доводиться відслідковувати, вони намагаються одночасно відповідати меншій кількості повторень, поки збіг всього шаблону не буде знайдено. Як результат, коли матч нарешті відбудеться, жадібне повторення відповідатиме якомога більше повторів.
Як ?
кількісний показник повторення перетворює цю поведінку на не жадібну , її також називають неохочею ( наприклад, Java ) (а іноді і "лінивою"). На відміну від цього , це повторення спочатку намагається відповідати , як кілька повторень , наскільки це можливо, і якщо це не працює , і вони повинні повернутися назад, вони починають відповідність ще одну REPT раз. В результаті, коли матч , нарешті , відбувається, неохоче повторення буде відповідати , як кілька повторень , наскільки це можливо.
Список літератури
Приклад 1: Від А до Я
Порівняємо ці дві закономірності: A.*Z
і A.*?Z
.
З огляду на наступний вхід:
eeeAiiZuuuuAoooZeeee
Шаблони дають такі збіги:
Спершу зупинимось на тому, що A.*Z
робить. Коли він відповідає першому A
, той .*
, будучи жадібним, спочатку намагається відповідати якомога більше .
.
eeeAiiZuuuuAoooZeeee
\_______________/
A.* matched, Z can't match
Оскільки Z
не відповідає, двигун відхиляється, а .*
потім повинен відповідати одному меншому .
:
eeeAiiZuuuuAoooZeeee
\______________/
A.* matched, Z still can't match
Це відбувається ще кілька разів, поки нарешті ми не дійшли до цього:
eeeAiiZuuuuAoooZeeee
\__________/
A.* matched, Z can now match
Тепер Z
може збігатися, тому загальний шаблон відповідає:
eeeAiiZuuuuAoooZeeee
\___________/
A.*Z matched
Навпаки, неохоче повторення в A.*?Z
перших матчах .
якнайменше, а потім більше .
необхідних. Це пояснює, чому він знаходить дві збіги у вхідних даних.
Ось наочне зображення того, що відповідність двох моделей:
eeeAiiZuuuuAoooZeeee
\__/r \___/r r = reluctant
\____g____/ g = greedy
Приклад: Альтернатива
У багатьох програмах два матчі на наведеному вище вкладі - це те, що бажано, тому неохоче .*?
використовується замість жадібного, .*
щоб запобігти перевтомі. Однак для цієї конкретної моделі є краща альтернатива, використовуючи заперечений клас символів.
Шаблон A[^Z]*Z
також знаходить ті ж самі збіги, що і A.*?Z
візерунок для вищевказаних даних ( як це видно на ideone.com ). [^Z]
це те, що називається запереченим класом символів : воно відповідає будь-якому, але крім Z
.
Основна відмінність між двома шаблонами полягає у продуктивності: будучи більш суворими, клас заперечених символів може відповідати лише одним способом для заданого вводу. Не має значення, якщо ви використовуєте жадний або неохоче модифікатор для цього шаблону. Насправді в деяких ароматах ви можете зробити ще краще і використовувати те, що називається присвоєним кількісним показником, який зовсім не відкликається.
Список літератури
Приклад 2: Від А до ЗЗ
Цей приклад повинен бути ілюстративним: він показує, як жадібні, неохотні та заперечені шаблони класів символів по-різному відповідають однаковому входу.
eeAiiZooAuuZZeeeZZfff
Це відповідники для наведеного вище вводу:
Ось наочне зображення того, що вони відповідали:
___n
/ \ n = negated character class
eeAiiZooAuuZZeeeZZfff r = reluctant
\_________/r / g = greedy
\____________/g
Пов'язані теми
Це посилання на запитання та відповіді про stackoverflow, які охоплюють деякі теми, які можуть зацікавити.
Одне жадне повторення може перевершити інше