Візуальний генератор формальних виразів

Всі розробники рано чи пізно стикаються з формальними виразами. Практично в 100% випадків нам абсолютно не подобається їх складати, вважаючи це побічною роботою, не пов'язаною з програмуванням.

Більшість з нас, вперше зіткнувшись з даною проблемою, починають забивати в пошукових системах щось типу: «regexp online generator» і на свій превеликий жаль усвідомлюють що гугл зламався всі результати в пошуку є сервісами для перевірки коректності вже складеного регулярного виразу (або я погано гуглив).

А як же скласти цей формальний вираз?

Донедавна існувало 2 відповіді на це питання:

  1. Вивчити документацію з формальних виразів і формалізувати сам
  2. Попросити когось більш досвідченого зробити це за вас

Тепер, після декількох місяців розробки, радий представити і 3-ю відповідь:

"Генератор формальних виразів

Історія

Давним давно, в одному проекті прийшов досить цікавий і складний запит від внутрішніх користувачів. Персоналу технічної підтримки потрібно було самим задавати правила валідації для певних полів, різним користувачам. Правила повинні були часто і дуже оперативно змінюватися.

Як і будь-який хороший розробник, ваш покірний слуга природно почав з пошуку вже готових рішень. Нічого підходящего не знайшлося і довелося приступити до дуже примітивної реалізації. На складну, як зазвичай, не було ні коштів ні часу.

Але ця проблема його дуже сильно зачепила і ось тепер, нарешті, він радий представити вам плоди своїх праць.

Почнемо

Для початку вирішив зробити веб-сервіс. Хотілося зробити максимально просто (для більш широкого кола людей), щоб своє правило для валідації змогли скласти не тільки програмісти, але і люди які далекі від програмування (модератори/адміністратори).

Ось сам інтерфейс:

Як і очікувалося, новому користувачеві взагалі нічого незрозуміло і тому довелося розробити ввідний інтерактивний курс:

Завжди виступаю проти модальних вікон і попапів, але в цьому випадку мені здається їх все ж таки цілковито використовувати. Можна назвати це «вітальним повідомленням».

А ось і сам інтерактивний курс, точніше його частина:

Також ви можете увімкнути показ окремих підказок незалежно чи пройдете ви введений курс, або відмовтеся від нього.

А що ж щодо функціоналу?

Перше що впадає в очі - це «Приклади» і зроблено це неспроста. Для початку, я настійно рекоммендую вибрати найбільш близький для вашого завдання приклад. Ви можете просто перемикатися між некоректним і коректним варіантом для більш простого розуміння прикладів. Потім можете змінити вибраний вами приклад так, як самі побажаєте. З часом список прикладів буде розширюватися:

Далі йде те, заради чого це все і затівалося - згенерований Регулярний Вираз:

Тут хотілося б трохи зупинитися і розповісти детальніше.

З самого початку мені хотілося створити інструмент не обмежує користувачів у створенні багатоскладних регулярок і в той же час зробити інтерфейс максимально простим. А на ділі, скільки разів кардинально змінювався інтерфейс я вже і з рахунку збився. Також довелося кілька разів переписувати частину логіки самого генератора (ядро). І не тому що архітектура була погано продумана, а через те що деякі варіанти просто не були враховані. А варіантів - величезна безліч.

Ще хотілося б розповісти про можливості. Зараз можна створювати регулярку з групами/підгрупами, визначати опціональні частини (не обов'язкові), вказувати конкретні символи (у інших буде визначатися тип), вказати тип - «будь-який символ» і блокувати певні символи в конкретній частині регулярки. Ви можете досить просто створити регулярку не тільки для слова, але і для словосполучення і навіть речення. Доступна генерація регулярок як на латиниці і так на кирилиці (окремо і разом). У міру додавання додаткових локалізацій інтерфейсу, планується підтримка регулярок і для інших писемностей.

До речі, не лякайтеся, що формальний вираз завжди червоного кольору. Це не символізує помилку, а зроблено лише для того, щоб акцентувати вашу увагу на цій вкрай важливій інформації.

Далі за порядком йде «Тестове поле»

Тут відбувається перевірка введеного тестового значення на відповідність згенерованому регулярному виразу. І відбувається вона «на льоту». Нічого натискати не потрібно. Тим самим ви можете набагато швидше і зручніше перевірити безліч варіантів.

Під полем вставки відображається опис автоматично створеного правила.

Є варіант з описом правила у вигляді помилки, коли введене тестове значення не відповідає згенерованому правилу/регулярці:

На даному прикладі видно як спрацьовує перевірка на заблоковані символи:

  • «» @ «» до другої «» @ «»;
  • «» -- «» у будь-якій частині імені домену другого рівня;
  • «» - «» в самому кінці домену другого рівня, непослідовно перед символом «» «».;

Опис заблокованих символів у правилі відображається не дуже зрозуміло. Трохи пізніше воно буде приведено до такого ж виду як і опис основної частини правила.

Також є варіант з описом правила в окремому блоці, коли введене тестове значення відповідає згенерованому правилу/регулярці:

Хотілося б роз'яснити значення кольорів з частинами правила:

  1. зелений - правильно
  2. жовтий - опціонально
  3. червоний - некоректно

Створений формальний вираз може мати не тільки обов'язкові частини, але також і опціональні. Хочу також зазначити, що автоматичний опис правила робився саме для майбутнього плагіну, але відмінно показав себе і в даному веб-сервісі.

Ядро (UI)

Ось і нарешті ми дісталися до останнього блоку по порядку, але не за значенням. Я особисто вважаю цей блок - ядром всього сервісу. Саме тут Генератор отримує всі необхідні вхідні дані, які згодом обробляє і видає вже готовий результат. До речі, вся логіка реалізована тільки на клієнті. Веб сервіс взагалі не має серверного коду.

Спочатку вкрай важливо зрозуміти що машина не вміє читати думки повинна отримати хоч якусь інформацію, щоб проаналізувати її і видати хоч якийсь результат. Чим правильнішими і лаконічнішими будуть приклади, тим правильнішим і лаконічнішим буде результат. Порядок прикладів абсолютно ні на що не впливає.

Тут можна дуже довго і нудно розповідати що і як потрібно вводити, але мені здається це буде набагато простіше зрозуміти за допомогою прикладів, яких там досить багато. І взагалі, матеріалу з описом як і що працює вистачить ще на одну велику статтю.

А ти не забув зберегтися?

Після того, як ми натиснули кнопку «Генерувати», у нас згенерувався регулярний вираз. Тепер ми можемо зберегти його. Про всяк випадок хочу уточнити що зберігається воно тільки в пам'яті браузера (localstorage).

Після натискання кнопки «Зберегти» з'являється діалогове вікно:

Ви можете вручну ввести опис для правила або переключитися на автоматичний опис як у прикладі нижче. Також вам потрібно ввести назву для правила:

Цей функціонал був розроблений з розрахунком на майбутній плагін, але став у нагоді і в даному веб-сервісі.

Насправді, як у випадку з прикладами так і з власними правилами, зберігається не згенероване правило, а просто вхідні дані і кожен раз коли ви перемикаєте правило - спрацьовує логіка генератора. Це дуже зручно при виправленні багів у логіці самого генератора. Тим самим навіть збережені правила будуть працювати з останньою версією вже виправленого генератора.

Додаткові можливості

Я розташував їх за пріоритетом:

  1. Автоматичне збереження даних в Url параметри. І це відбувається відразу після натискання на кнопку «Генерувати», або при перемиканні прикладів або збережених правил. Ви можете скинути комусь посилання і при відкритті сторінки інший користувач побачить саме те, що ви вводили раннє. Це досить зручно.
  2. Повна локалізація всього контенту. Існуючі модулі локалізації мені сильно не подобалися, тому ваш покірний слуга створив свій велосипед дуже простий модуль. Всього десяток рядків коду. Вибрана мова зчитується з Url і записується в Url, зберігається в Localstorage. Особливо приємно додавати нові мови, оскільки текст береться тільки з одного дуже простого JSON файлу для відповідної мови. Віддав файлик перекладачам - отримав ще одну мову.
  3. Повідомлення про нову версію програми. Цей веб-сервіс - це односторінковий веб-додаток (буквально). З особистого досвіду знаю що користувач може місяцями не перезавантажувати односторінковий додаток і це якраз правильно. Але що робити якщо вийшла нова версія? Як сповістити про це користувача? Було розроблено модуль, який опитує збережений JSON файл з вказаним інтервалом часу і як тільки записана нова версія не відповідає попередній - показується ось таке повідомлення:

Технології

Ось основний стек технологій за допомогою якого вдалося все це реалізувати:

  • TypeScript 2.0 + SystemJS
  • Angular 1.5 (з компонентами)
  • Angular-Material 1.x
  • IntroJS

Код написано в повному Angular 2 Code Style (навіть з декораторами), що в майбутньому дозволить дуже просто мігрувати (чекаю тільки Material2).

Ув'язнення

У подальших планах - зробити повноцінний плагін, який дозволить задавати правила валідації одночасно для клієнта і для сервера прямо з інтерфейсу. Мені здається це виявиться дуже зручним і практичним рішенням. Потім можна розвинути цю ідею і створити навіть «Visual Form Builder» на основі як-би стандарту: «JSON Schema», з яким мені довелося попрацювати свого часу.

Якщо ви захочете зробити щось аналогічне, я буду тільки за і навіть допоможу порадами. Вважаю що: «Сама ідея практично нічого не варта, варта її безпосередня реалізація».

На закінчення, хочу дозволити собі невеликий відступ. Якщо ти розробник-мрійник, як і автор статті, який отримує кайф від своєї роботи, особливо коли вона кидає тобі виклик і хоч трохи, але все ж вирішує проблеми інших людей, тоді ти швидше за все на правильному шляху. Гірше, коли такій людині доводиться гнатися за грошима, якимись матеріальними благами, щоб відповідати незрозумілим соціальним стандартам або виконувати нудну, дурну і рутинну роботу щоб просто прогодувати себе, свою сім'ю. Здається не правильним жертвувати своїми мріями, ідеями, прагненнями і часом на догоду простим папірцям. Але в той же час автор статті нікого не спонукає прямо зараз все взяти і кинути. Кожен повинен зробити свій вибір сам і коли для цього настане дійсно відповідний час.