Що означає «зараз у вас дві проблеми»?


200

Є популярна цитата Джеймі Завінського :

Деякі люди, стикаючись з проблемою, думають, "я знаю, я буду використовувати регулярні вирази". Зараз у них дві проблеми.

Як слід розуміти цю цитату?


46
Друга проблема полягає в тому, що вони використовують регекс і досі не вирішили першої проблеми, отже, 2 проблеми.
Ampt

24
@Euphoric - на насправді, хороший код є коротким - але не будучи загадково коротким.
Стів314

24
@IQAndreas: Я думаю, що він призначений бути напівжартливим. Зауваження, яке робиться, полягає в тому, що якщо ви не обережні, використання регулярних виразів може зробити щось гірше, а не краще.
FrustratedWithFormsDesigner

145
Деякі люди, намагаючись щось пояснити, думають: «Я знаю, я використаю цитату Джеймі Завінського». Тепер вони мають пояснити дві речі.
детлі

Відповіді:


220

Деякі технології програмування, як правило, не розуміються програмістами ( регулярні вирази , плаваюча точка , Perl , AWK , IoC ... та інші ).

Це можуть бути дивовижно потужні інструменти для вирішення правильного набору проблем. Зокрема, регулярні вирази дуже корисні для відповідності звичайним мовам. І в цьому суть проблеми: мало хто знає, як описати звичайну мову (це частина теорії інформатики / лінгвістики, яка використовує кумедні символи - про це можна прочитати в ієрархії Хомського ).

Якщо ви маєте справу з цими речами, якщо ви їх неправильно використовуєте, навряд чи ви вирішили свою первісну проблему. Використання регулярних виразів для відповідності HTML (далеко надто поширене явище) означатиме , що ви будете пропустити крайні випадки. А тепер у вас все ще є оригінальна проблема, яку ви не вирішили, і ще одна непомітна помилка, що обертається навколо, що була введена за допомогою неправильного рішення.

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

Запорукою підтримки програмного забезпечення є написання коду, що підтримується. Використання регулярних виразів може суперечити цій меті. Працюючи з регулярними виразами, ви написали міні-комп’ютер (зокрема, недетермінований автомат з кінцевими станами ) спеціальною мовою, специфічною для домену. Неважко написати цією мовою еквівалент "Hello world" та завоювати до цього рудиментарну впевненість, але далі потрібно гартувати розуміння звичайної мови, щоб уникнути написання додаткових помилок, які важко визначити та виправити (адже вони не є частиною програми, в якій є регулярний вираз).

Отже, у вас з’явилася нова проблема; ви вибрали інструмент регулярного вираження для його вирішення (коли це недоречно), і у вас зараз є дві помилки, яких обидва важче знайти, оскільки вони заховані в іншому шарі абстракції.


8
Я не впевнений, що сам perl належить до переліку технологій, які недостатньо зрозуміли програмісти;)
crad

21
@crad тим більше, що говорилося і про perl ... Багато людей чули, як це популяризується там. Мені все одно подобається плаваюча точка в розмові про rand: "Зараз у вас є проблеми 2.00000152"

56
@crad Деякі люди, стикаючись з проблемою, думають, "я знаю, я буду використовувати perl". Тепер у них проблеми з $ (^ @ #% () ^%) (#).
Майкл Хемптон

4
@Jens, якщо що завгодно, додаткова потужність PCRE проти традиційного регулярного вираження робить його більш спокусливим рішенням і більш складним у підтримці. Кінцеві автомати, що відповідають PCRE, досліджуються в Розширенні Кінцевих Автоматичних даних для ефективного відповідності Perl-сумісних регулярних виразів ... та його нетривіальна річ. Принаймні , з традиційним регулярним виразом, можна отримати їх голова навколо нього не надто багато клопоту , як тільки необхідні поняття зрозумілі.

6
Ви робите гарний момент. регулярні вирази - це фактично друга, нетривіальна мова. Навіть якщо оригінальний програміст володіє основною мовою та використовуваним ароматом регулярного вираження, додавання "другою мовою" означає нижчі шанси, що технічні працівники знають і те, і інше. Не кажучи вже про те, що читабельність за регулярними виразами часто нижча, ніж мова "хост".
JS.

95

Регулярні вирази - особливо нетривіальні - потенційно важко кодувати, розуміти та підтримувати. Потрібно лише переглянути кількість запитань на тезі Stack Overflow, [regex]де запитуючий припустив, що відповідь на їх проблему - це регулярний вираз і згодом застряг. У багатьох випадках проблему можна (а можливо, і слід) вирішити по-іншому.

Це означає, що якщо ви вирішили використовувати регулярний вираз, у вас виникли дві проблеми:

  1. Первісна проблема, яку ви хотіли вирішити.
  2. Підтримка регулярного вираження.

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


27
І ще гірше: вони просто досить потужні, щоб підманювати людей намагатися використовувати їх для розбору речей, які вони не можуть, як HTML. Дивіться численні запитання на тему "як я розбираю HTML?"
Френк Ширар

6
Для певних ситуацій регулярний вираз є приголомшливим. У багатьох інших випадках не так багато. З іншого боку - це жахлива яма відчаю. Проблема часто виникає, коли хтось дізнається про них вперше і починає бачити програми всюди. Ще одна відома приказка: "Коли єдиним інструментом у вас є молоток, все виглядає як цвях".
Тодд Вільямсон

3
Чи означає це, що за кількістю питань у тезі SO [c #] це найскладніша для розуміння мова програмування?

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

5
"В основному, я думаю, що він означає, що ви повинні використовувати регулярний вираз, якщо немає іншого способу вирішення вашої проблеми. Будь-яке інше рішення буде простіше кодувати, підтримувати та підтримувати." - серйозно не погоджуюся .. Regexes - прекрасний інструмент, просто потрібно знати їх межі. Дуже багато завдань можна кодувати елегантніше за допомогою регулярних виразів. (але, щоб зробити приклад, ви не повинні використовувати їх для розбору HTML)
Karoly Horvath

69

Це переважно жартівливий жарт, хоч із зерном правди.

Є кілька завдань, для яких регулярні вирази - прекрасна відповідність. Одного разу я замінив 500 рядків рукописного рекурсивного коду синтаксичного аналізатора на один регулярний вираз, на повне налагодження якого пішло близько 10 хвилин. Люди кажуть, що регулярні вирівнювання важко зрозуміти та налагодити, але належним чином застосувати їх не так вже й складно, як і величезний розроблений вручну аналізатор. У моєму прикладі знадобилося два тижні, щоб налагодити всі крайні випадки рішення, що не піддається повторному виведенню.

Однак перефразовуючи дядька Бена:

З великою виразністю настає велика відповідальність.

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

Деякі речі спочатку виглядають як гарне завдання для регулярних виразів, але ні. Наприклад, що завгодно з вкладеними маркерами, як-от HTML. Іноді люди використовують регулярний вираз, коли більш простий метод більш зрозумілий. Наприклад, string.endsWith("ing")простіше зрозуміти, ніж еквівалентний регулярний вираз. Іноді люди намагаються врізати велику проблему в єдиний регулярний вираз, де доцільніше розбити його на частини. Іноді людям не вдається створити відповідні абстракції, повторюючи регулярний вираз замість того, щоб створити добре названу функцію, щоб виконувати ту саму роботу (можливо, реалізовану внутрішньо за допомогою регулярного вираження).

З певних причин регекси мають дивну тенденцію до створення сліпої плями до нормальних принципів інженерії програмного забезпечення, таких як одна відповідальність і DRY. Ось чому навіть люди, які їх люблять, вважають їх часом проблематичними.


10
Чи дядько Бен також не сказав: "Ідеальні результати кожного разу"? Можливо, тому люди настільки радіють регексам ...
Анджей Дойл

4
Проблема з регулярним виразом щодо HTML, який відтягує недосвідчених розробників, полягає в тому, що HTML має без контексту граматику, а не регулярну: regex може використовуватися для простого розбору HTML (або XML) (наприклад, захоплення URL-адреси з названого тегу прив’язки), але не підходить для нічого складного. Для цього більш відповідним є розбір DOM. Пов'язане читання: Ієрархія Хомського .

53

Джефф Етвуд викладає іншу інтерпретацію в публікації в блозі, обговорюючи цю цитату: Регулярні вирази: Тепер у вас є дві проблеми (спасибі Ейфорику за посилання)

Аналізуючи повний текст публікацій Джеймі в оригінальній темі 1997 року, ми виявляємо наступне:

Природа Перла заохочує використання регулярних виразів майже до виключення всіх інших прийомів; вони далеко і є найбільш "очевидним" (принаймні, людям, які не знають кращого) способу дістатися від точки А до точки Б.

Перша цитата - занадто гліб, щоб сприймати її серйозно. Але з цим я повністю згоден. Ось то, що Джеймі намагався зробити: не те, що регулярні вирази самі по собі є злими, але в тому, що надмірне використання регулярних виразів є злом.

Навіть якщо ви дійсно в повній мірі зрозуміти регулярні вирази, ви біжите в The Golden Hammer проблеми, намагаючись вирішити проблему з регулярними виразами, коли це було б простіше і зрозуміліше , щоб зробити те ж саме з регулярним кодом (дивись також CodingHorror: Regex використання проти зловживання Regex ).

Є ще одна публікація в блозі, в якій розглядається контекст цитати, і йдеться про детальніше, ніж Етвуд: Блог Джефрі Фрідла: Джерело відомої цитати "Зараз у вас є дві проблеми".


3
На мій погляд, це найкраща відповідь, оскільки це додає контексту. Критика реджексів jwz була стільки ж, скільки про Перла.
Евікатос

3
@Evicatos Ще одне дослідження, проведене на тій же темі 1997 року, було проведено в іншій публікації блогу: regex.info/blog/2006-09-15/247
IQAndreas

30

З цією цитатою відбувається кілька речей.

  1. Цитата є повторенням більш раннього анекдоту:

    Щоразу, коли стикаються з проблемою, деякі люди кажуть "Дозвольмо використовувати AWK". Зараз у них дві проблеми. - Д. Тілбрук

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

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

  3. Хоча смішно, як жарт, вам потрібно порівняти складність нерегексичного рішення зі складністю рішення регулярного виразів + додаткова складність включення регулярних виразів. Можливо, варто вирішити проблему з регулярним виразом, незважаючи на додаткові витрати на додавання регулярних виразів.


21

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

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


Ось тривіальний приклад:

^(?:[^,]*+,){21}[^,]*+$


Що насправді не так складно читати чи підтримувати, але це ще простіше, коли це виглядає так:

(?x)    # enables comments, so this whole block can be used in a regex.
^       # start of string

(?:     # start non-capturing group
  [^,]*+  # as many non-commas as possible, but none required
  ,       # a comma
)       # end non-capturing group
{21}    # 21 of previous entity (i.e. the group)

[^,]*+  # as many non-commas as possible, but none required

$       # end of string

Це трохи надмірний приклад (коментування $подібне до коментування i++), але, очевидно, не повинно бути проблем з читанням, розумінням та підтримкою цього.


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


1
Звичайно, але я не шукаю обговорень достоїнств регулярних виразів, і я не хотів би, щоб ця дискусія йшла таким шляхом. Я просто намагаюся зрозуміти, до чого він потрапляв.
Пол Біггар

1
Тоді посилання в коментарі livibetter повідомляє вам про те, що вам потрібно знати. Ця відповідь просто вказує на те, що регулярні виразки не повинні бути незрозумілими, і, отже, цитата є нісенітницею.
Пітер Бауфтон

8
У чому сенс використання *+? Чим це відрізняється (функціонально) від просто *?
Тімві

1
Хоча те, що ви говорите, може бути правдою, але це не дає відповіді на це конкретне запитання. Ваша відповідь зводиться до "на мою думку, що цитата зазвичай не відповідає дійсності". Питання не в тому, правда це чи ні, а в тому, що означає цитата.
Брайан Оуклі

2
В *+цьому випадку робити буквально немає сенсу ; все закріплено і може за один проїзд зіставитись автоматом, який може нараховувати до 22. Правильний модифікатор для цих наборів без комах є просто старим *. (Більше того, тут також не повинно бути різниць між жадібними та не жадібними алгоритмами відповідності. Це надзвичайно простий випадок.)
Дональди,

14

На додаток до відповіді ChrisF - що регулярні вирази "важко кодувати , зрозуміти та підтримувати", є ще гірше: вони просто досить потужні, щоб обдурити людей, намагаючись розібрати їх, щоб вони не могли, наприклад, HTML. Дивіться численні запитання на тему "як я розбираю HTML?" Наприклад, єдина найбільш епічна відповідь у всьому ТАК!


14

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

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

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


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

4
@ Thorbjørn Ravn Andersen: Це швидше обмеження, ніж проблема. Проблема є лише в тому випадку, якщо ви намагаєтесь використовувати для цього регулярні вирази, і тоді це не проблема з регулярними виразами, це проблема з вибором методу.
Guffa

1
Ви можете використовувати REs дуже добре для лексеру (ну, для більшості мов), але збірка потоку токенів у дерево розбору (тобто розбір ) формально поза ними.
Стипендіати доналу

10

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

Ви стверджуєте, що він може виконати роботу сотні рядків коду, але ви також можете зробити аргумент, що 100 рядків чіткого, стислого коду краще, ніж один рядок регулярного виразів.

Якщо вам потрібні певні докази цього: Ви можете перевірити цей SO Classic або просто розчесати тег SO Regex


8
Жодне з тверджень у вашому першому реченні не відповідає дійсності. Regex не є особливо складним, і, як жоден інший інструмент, вам потрібно це чудово знати, щоб вирішити проблеми. Це просто FUD. Ваш другий абзац очевидно смішний: звичайно, ви можете зробити аргументи. Але це не дуже добре.
Конрад Рудольф

1
@KonradRudolph Я думаю, що факт існування численних інструментів генерації та перевірки регулярних виразів свідчить про те, що регулярний вираз є складним механізмом. Це не читається людиною (за дизайном) і може спричинити повну зміну потоку для того, щоб хтось модифікував або писав фрагмент коду, який використовує регулярний вираз. Що стосується другої частини, я думаю, що це зрозуміло, що це має на увазі велике групування знань про P.SE та висловом "Налагодження коду вдвічі складніше, ніж його написати, тому якщо ви пишете найрозумніший код, який можете, ви , за визначенням, недостатньо розумні, щоб налагодити це "
Ampt

2
Це не належний аргумент. Так, звичайно регулярний вираз є складним. Але це стосується інших мов програмування. Regex значно менш складний, ніж більшість інших мов, і інструменти, які існують для регулярного вирівнювання, є карликовими інструментами розробки для інших мов (FWIW. Я широко працюю з регулярним виразом, і таких інструментів я ніколи не використовував ...). Проста правда, що навіть складний регулярний вираз простіший, ніж еквівалентний код нерозбірного аналізу.
Конрад Рудольф

@KonradRudolph Я думаю, що ми маємо принципову незгоду щодо визначення цього слова просто. Я скажу вам, що регулярний вираз може бути більш ефективним або навіть більш потужним, але я не думаю, що це просте слово, яке комусь спадає на думку, коли ви думаєте про регекс.
Ampt

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

7

Значення має дві частини:

  • По-перше, ви не вирішили оригінальну проблему.
    Це, мабуть, стосується того, що регулярні вирази часто пропонують неповне вирішення загальних проблем.
  • По-друге, тепер ви додали додаткових труднощів, пов'язаних з обраним вами рішенням.
    Що стосується регулярних виразів, то додаткова складність, ймовірно, стосується складності, ремонтопридатності або додаткової складності, пов’язаної з підключенням регулярних виразів до проблеми, яку він не повинен був вирішити.

7

Коли ви запитаєте про це у 2014 році, було б цікаво зосередитись на ідеологіях мов програмування контексту 1997 року порівняно з сучасним. Я не буду тут вступати в цю дискусію, але думки про Perl і Perl дуже змінилися.

Однак, щоб зупинитися на контексті 2013 року ( de l'eau a coulé sous les ponts depuis), я б запропонував зосередитись на реконструкції в цитатах, використовуючи відомий комікс XKCD, який є прямою цитатою твору Джеймі Завінського :

Комікс із XKCD про реджекси, Perl та проблеми

По- перше у мене були проблеми , щоб зрозуміти цей комікс , тому що це було посилання на Завінського цитатою, і цитата з Джей-Z тексти пісень, і посилання ГНУ program --help -zпрапор 2 , так, що це було занадто багато культури для мене , щоб зрозуміти це.

Я знав, що це весело, я відчував це, але я не знав чому. Люди часто жартують з приводу Perl та реджексів, тим більше, що це не найшвидша мова програмування, насправді не знаю, чому це повинно бути весело ... Можливо, тому, що зловмисники Perl роблять дурні речі .

Тож початкова цитата здається саркастичним жартом, заснованим на реальних життєвих проблемах (біль?), Спричинених програмуванням інструментами, які шкодять. Так само, як молоток може завдати шкоди муляру, програмуючи інструменти, які не є тими, які розробник обрав би, якщо він може нашкодити (мозок, почуття). Іноді виникають великі дебати щодо того, який інструмент найкращий, але це майже нічого не варто, оскільки це проблема вашого смаку чи смаку вашої команди програмування , культурних чи економічних причин. Ще один чудовий комікс XKCD про це:

Комікс XKCD про дебати про засоби програмування

Я можу зрозуміти, що люди відчувають біль від регулярних виразів, і вони вважають, що інший інструмент краще підходить для того, для чого призначені регулярні виразки. Коли @ karl-bielefeldt відповідає на ваше запитання з великою експресивністю , ця відповідальність приносить велику відповідальність , і реджекси особливо хвилюють це. Якщо розробник не піклується про те, як s-він поводиться з регулярними виразами, це врешті-решт буде болем для людей, які підтримуватимуть код пізніше.

Я закінчу цією відповіддю про реконструкцію котирувань цитатою, що показує типовий приклад з найкращих практик « Perl Best Practices» від Damian Conw ay (книга 2005 року).

Він пояснює, що писати такий зразок:

m{'[^\\']*(?:\\.[^\\']*)*'}

... не є більш прийнятним, ніж написання такої програми :

sub'x{local$_=pop;sub'_{$_>=$_[0
]?$_[1]:$"}_(1,'*')._(5,'-')._(4
,'*').$/._(6,'|').($_>9?'X':$_>8
?'/':$")._(8,'|').$/._(2,'*')._(
7,'-')._(3,'*').$/}print$/x($=).
x(10)x(++$x/10).x($x%10)while<>;

Але це можна переписати , це все ще не симпатично, але принаймні зараз воно приживеться.

# Match a single-quoted string efficiently...
m{ '            # an opening single quote
    [^\\']*     # any non-special chars (i.e., not backslash or single quote)
    (?:         # then all of...`
    \\ .        # any explicitly backslashed char
    [^\\']*     #    followed by any non-special chars
    )*          # ...repeated zero or more times
    '           # a closing single quote
}x

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


2
/* Multiply the first 10 values in an array by 2. */ for (int i = 0 /* the loop counter */; i < 10 /* continue while it is less than 10 */; ++i /* and increment it by 1 in each iteration */) { array[i] *= 2; /* double the i-th element in the array */ }
5gon12eder

6

Якщо є одне, чого слід дізнатися з інформатики, це ієрархія Хомського . Я б сказав, що всі проблеми з регулярними виразами виникають із спроб розбору з ним контекстної граматики. Коли ви можете встановити обмеження (або вважаєте, що можете встановити обмеження) рівнів вкладення в CFG, ви отримуєте ці довгі і складні регулярні вирази.


1
Так! Люди, які вивчають регулярні вирази без цієї частини CS-тексту, не завжди розуміють, що є лише деякі речі, які математично не може зробити регулярний вираз .
бензадо

5

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

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

Отже, якщо хтось звик до "ага, мені потрібно підібрати текст окремо, я буду використовувати регулярний вираз", легко піти вниз по цьому маршруту, коли вам потрібно щось, що ближче до висувного автомата, аналізатора CFG або ще потужніші граматики. Зазвичай це закінчується сльозами.

Отже, я думаю, що цитата не стільки грюкає регулярними виразками, вони користуються ними (і добре використовуються, вони дуже корисні), але надмірна залежність від регулярних виразів (або, конкретно, некритичного їх вибору) .


3

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

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

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

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


1
FWIW, арифметика з плаваючою комою є більш хитрою, ніж РЕ, але здається простішою. Остерігайся! (Принаймні, хитрі РЕ виглядають небезпечно.)
Донори

3

Мою улюблену глибоку відповідь на це дає відомий Роб Пайк у публікації в блозі, відтвореній із внутрішнього коментаря до коду Google: http://commandcenter.blogspot.ch/2011/08/regular-expressions-in-lexing- і.html

Підсумок полягає в тому, що вони не погані , але їх часто використовують для завдань, для яких вони не обов'язково підходять, особливо якщо мова йде про лексику та аналіз певних даних.

Регулярні вирази важко записати, важко записати, і вони можуть бути дорогими відносно інших технологій ... Лексери, з іншого боку, досить легко писати правильно (якщо не настільки компактно), і дуже легко перевірити. Розглянемо пошук буквено-цифрових ідентифікаторів. Написати не регулярно (наприклад, "[a-ZA-Z _] [a-ZA-Z_0-9] *"), але насправді не набагато складніше написати як простий цикл. Однак продуктивність циклу буде значно вищою і буде містити набагато менше коду під обкладинками. Бібліотека регулярних виразів - це велика річ. Використовувати один для розбору ідентифікаторів - це як використовувати Ferrari, щоб піти в магазин за молоком.

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


0

Це пов’язано з епіграмою № 34 Алана Перліса:

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

Отже, якщо ви обрали рядок символів як структуру даних (і, природно, код на основі регулярних виразів як алгоритми для управління ним), у вас виникає проблема, навіть якщо вона працює: поганий дизайн навколо невідповідного представлення даних, який важко розширення та неефективність.

Однак часто це не працює: оригінальна проблема не вирішена, і тому в цьому випадку у вас є дві проблеми.


0

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

Однак, коли реджекси отримують більш складні сервальні питання, вони піднімають голову.

  1. Синтаксис регулярних виразів оптимізований для простого узгодження, більшість символів відповідають собі. Це чудово підходить для простих шаблонів, але як тільки ви закінчите більше ніж кілька рівнів вкладеності, ви отримаєте щось схоже на шум лінії, ніж добре структурований код. Я здогадуюсь, що ви можете написати регулярний вираз як серію зв'язаних рядків з відступами та коментарями між ними, щоб показати структуру коду, але, здається, це рідко трапляється.
  2. Лише певні типи відповідності тексту добре підходять до регулярних виразів. Часто ви виявляєте, що отримуєте швидкий і брудний аналізатор на основі регулярних виразів для роботи якоїсь мови розмітки, але тоді ви намагаєтеся охопити більше кутових випадків, і ви виявите, що регулярні виразки стають все складнішими і менш читаються.
  3. Часова складність регулярного виразів може бути необов’язковою. Не так складно закінчити шаблон, який чудово працює, коли він відповідає, але має складність O (2 ^ n) у певних випадках невідповідності .

Таким чином, все занадто просто починати з проблеми обробки тексту, застосовувати до неї регулярні вирази і закінчувати двома проблемами, оригінальною проблемою, яку ви намагалися вирішити, і мати справу з регулярними виразами, які намагаються вирішити (але не вирішувати правильно) первісна проблема.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.