Java Script підручник | Жадібні і ледачі квантіфікатори в регулярних виразах
- Жадібні і ледачі квантіфікатори в регулярних виразах
- жадібний пошук
- лінивий режим
- підсумки
- завдання
- Знайти HTML-теги
Жадібні і ледачі квантіфікатори в регулярних виразах
Доброго дня! Продовжуємо розмову про квантіфікатор в регулярних виразах , Розпочатий в минулому уроці і сьогодні розглянемо що таке жадібні квантіфікатори і не дуже. Насправді квантіфікатори хоч на вигляд дуже проста, але місцями дуже хитра штука.
І треба дуже добре розуміти, яким чином відбувається пошук.
Давайте для прикладу розберемо ось такий приклад треба замінити в тексті лапки виду «...» на «лапки-ялинки»: «...».
Для цього треба знайти всі слова в таких лапках.
Регулярки може виглядати приблизно так: /».+»/g.
var reg1 = /".+"/g; var str1 = 'a "bitch" and her "room" is one'; alert (str1.match (reg1)); // "bitch" and her "room"То тут нас очікує невеликий сюрприз.
Замість того, щоб знайти два збіги «witch» і «broom», воно знаходить одне: «witch» and her «broom».
Це все відбувається через жадібність квантіфікаторов.
жадібний пошук
Для того щоб знайти збіг, звичайно використовується ось іакой алгоритм:
- Для позиції в пошуковому рядку
- Перевірити чи є збіг на даній позиції
- Зіставити з нею регулярний вираз, використовуючи квантіфікатори.
Це все в загальному, давайте розберемо все покроково.
- 1-ий символ шаблону - це лапки «. Движок намагається знайти її на 0-й позиції в рядку, але там є символ a, тому на цій позиції відповідності явно немає. Далі він переходить далі на 1ю, 2ю позицію в рядку і, виявляє лапки на 3-й позиції.
- Після того лапки була знайдена, далі движок буде перевіряти, чи знайдено відповідність для іншої частини шаблону. У нашому випадку наступний символ шаблону це. (крапка). Вона знаходить «будь-який символ», таким чином буква рядки 'w' підходить:
- Далі «будь-який символ» повторюється, так як варто квантіфікатор. +. Движок регулярних виразів бере один символ за іншим, до тих пір, поки у нього це получается.В даному випадку це означає «до кінця рядка»:
- Отже, наш текст закінчився, і движок регулярних виразів більше не зможе знайти «будь-який символ», він закінчить повторення для. + Та перейде до наступного символу шаблону. Наступний символ шаблону - це лапки. Її також необхідно знайти. А тут просходит наступне адже пошуковий текст завершився! І движок розуміє, що, напевно, взяв забагато. + Та починає йти назад. Іншими словами, він скоротить поточний збіг на 1 символ. Це так звана називається «фаза повернення». Тепер. + Відповідатиме майже вся рядок, за винятком 1-го символу, і движок ще раз намагається підібрати відповідність для залишку шаблону, починаючи з решти рядка. Так воь якщо останній символ рядка лапка ' »', то на цьому б усе й закінчилося. Але останній символ 'e', так що збіги немає.
- Далі движок зменшить число повторень. + Ще на 1 символ. Лапки ' »' не співпадатиме з 'n'.
- Движок продовжить відступати, він зменшить кількість повторень точки '.' до тих пір, поки залишок шаблону, тобто в даному випадку лапки ' »', не збіжиться.
- Збіг отримано. Подальший пошук збігів не дасть.
У жадібному режимі движок повторює квантіфікатор настільки багато раз, поки не буде знайдено відповідність.
Таким чином будь-який символ. + Повторюватиметься максимальну кількість разів, що і призведе до довгої рядку.
А нам хотілося, щоб кожен рядок в лапках була незалежним збігом? Для цього нам треба перемкнути квантіфікатор + в «ледачий» режим.
лінивий режим
Лінивий режим роботи квантіфікаторов - це протилежність жадібному, він дослівно означає «повторювати мінімальну кількість разів».
Для того щоб включити даний режим просто поставивши знак питання '?' після квантіфікатора: *? або +? або ?? для '?'.
Регексп /».+?»/g працює, як задумано - знаходить окремо bitch і room:
var reg1 = /".+?"/g; var str1 = 'a "bitch" and her "room" is one'; alert (str1.match (reg1)); // witch, broomЩоб в точності зрозуміти, як змінилася робота квантіфікатора, розберемо пошук по кроках.
- Перший крок - лапка ' »' знайдена на 3-й позиції:
- Другий крок - знаходимо довільний символ '.':
- А ось далі - оскільки стоїть ледачий режим роботи +, то регескп не повторюватиме точку (довільний символ) ще раз, а зупиниться на досягнутому і буде намагатися перевірити, чи є відповідність решти шаблону.
- Движок буде збільшувати кількість повторень точки на одне і буде намагатися знайти відповідність залишку шаблону ще раз. Знову осічка. Тоді движок буде збільшувати кількість повторень ще і ще ...
- Тільки на п'ятому кроці пошукової движок нарешті знаходить відповідність для залишку патерну:
- Оскільки пошук відбувається з прапором g, то він буде тривати з кінця поточного збіги, даючи ще один результат
У прикладі ми продемонстрували роботу ледачого режиму для + ?. Квантіфікатори +? �� ?? поводяться аналогічно.
Слід зазначити, що ліниво поширюється тільки на той квантіфікатор, після якого стоїть?.
А ось інші квантіфікатори залишаються жадібними.
наприклад:
alert ( "678 456" .match (/ \ d + \ d +? / g)); // 678 4- Шаблон \ d + намагатиметься знайти стільки цифр, скільки можливо так що він знайде 678 і зупинитися, оскільки символ пропуску '' не підходить під \ d.
- Далі в шаблоні пробіл, він збігається.
- Далі в шаблоні йде \ d + ?. Оскільки квантіфікатор вказано в ледачому режимі, тому він знайде цифру 4 і перевірить, чи є збіг із залишком шаблону. Але після \ d +? в шаблоні нічого не буде. А оскільки ледачий режим зайвий раз квантіфікатор не повторюватиме. Так як шаблон завершився, то шукати власне далі нічого. І ми отримаємо збіг 678 4.
- Наступний пошук буде продовжено з 5, але нічого не знайде.
підсумки
У квантіфікаторов є 2 режиму роботи:
Жадібний Режим за замовчуванням - движок буде повторювати його по-максимуму. А ось коли повторювати вже не можна, наприклад немає більше цифр для \ d +, він буде продовжувати пошук з решти тексту. Якщо збіг не знайдено - відступить назад, зменшивши кількість повторень. Лінивий Якщо вказати після квантіфікатора символ? він буде працювати в ледачому режимі. Тобто, він буде перед кожним повторенням перевіряти збіг частини шаблону на поточній позиції.завдання
Знайти HTML-коментарі
Знайдіть всі HTML-коментарі в тексті:
var re = ..регексп .. var str = '.. <! - Мій - коммент \ n тест -> .. <! ----> ..'; alert (str.match (re)); // '<! - Мій - коммент \ n тест ->', '<! ---->'Знайти HTML-теги
Створіть регулярний вираз для пошуку всіх (відкриваються і закриваються) HTML-тегів разом з атрібутамі.Прімер використання:
var re = / * ваш шаблон * / var str = '<> <a href="/"> <input type = "radio" checked> <b>'; alert (str.match (re)); // '<a href="/">', '<input type = "radio" checked>', '<b>'Якщо ви знайшли помилку, будь ласка, виділіть фрагмент тексту і натисніть Ctrl + Enter.
також читайте
А нам хотілося, щоб кожен рядок в лапках була незалежним збігом?Для того щоб включити даний режим просто поставивши знак питання '?
Після квантіфікатора: *?
Або +?
Або ?
Для '?
Квантіфікатори +?
? ?
Слід зазначити, що ліниво поширюється тільки на той квантіфікатор, після якого стоїть?
D + \ d +?