Регулярные выражения

Регулярные выражения

Это смешно. Стоит где-нибудь прилюдно упомянуть регулярные выражения — у народа делаются квадратные глаза и перехватывает дыхание. Кто ими пользуется — немы от восторга. Кто ими не пользуется — благоговейно трепещут. И те, и другие почитают их как божественное откровение, как высшее достижение всяческой разумности (пардон, чуть не сказал: "высшую меру").

А собственно, что такого? Всего-навсего язык для задания шаблонов поиска текстовых строк — ни на что другое он не годится, хотя иной раз осмеливается претендовать. Язык древний, набитый под завязку пережитками прошлого. Громогласные заявления о его мощи и удобстве — не более чем пропаганда. Да, свою работу он выполняет и вполне годится для использования в тех приложениях, на которые он рассчитан. Как и любой другой язык. Если кто-то к этому привык, он будет считать это удобным. Но существуют и другие возможности, которые, по большому счету, ничем не хуже.

Регулярные выражения придуманы для обслуживания операционных систем семейства Unix — управление системой в них сводится по большей части к редактированию текстовых файлов, и отчеты о состоянии системы также представляют собой текстовые файлы в неудобочитаемом формате — так что потребность в средствах выкапывания их таких файлов нужной информации вполне понятна. Традиция оказалась весьма живучей — и тестовый формат до сих пор используется в большинстве систем и приложений для журналирования, регистрации текущих событий и действий. Хотя, например, в системах управления базами данных было бы логичнее заносить данные в специальную базу в структурированном виде, а отчеты строить стандартными средствами. Одно время серьезным аргументом в пользу регулярных выражений служил исключительно текстовый характер HTML — действительно, анализ статических страниц прекрасно вписывался в идеологию поиска по шаблону. Однако реальные парсеры все-таки работают по-другому, намного эффективнее. А потом и сама возможность примитивной обработки текста из HTML испарилась, ибо основное содержание страниц нынче формируется динамически, генерируется на лету в реальном взаимодействии с пользователем. Искать что-то по шаблону в разнесенных по разным файлам скриптах и определениях стилей — дело неблагодарное. Допустим, на странице светится картинка с определенным названием — но названия как такового в исходном тексте страницы нет, оно комбинируется из отдельных элементов непосредственно при вызове изображения. Что тогда искать?

Современный документ — это не только, и не столько текст, сколько сложная комбинация объектов самого разного уровня. В них встроены запросы к базам данных, изображения, мультимедийные вставки, конструкторы формул, документооборотные элементы, средства визуализации, сценарии и формы. Проку от регулярных выражений здесь совершенно никакого. Документы обрабатываются соответствующими приложениями, в которых есть встроенные средства поиска и замены, плотно интегрированные с языком прикладного программирования. Если и требуется в каких-то случаях искать куски текста — особых наворотов тут не нужно, достаточно простейших шаблонов. Тем более, что искать приходится не просто строки, а строки в определенном контексте — например, с заданными параметрами форматирования. Стиль Unix до сих пор заставляет программистов запихивать все, что надо и не надо, в текстовые файлы — и потом с чувством глубокого удовлетворения заниматься их фильтрацией по регулярным выражениям. Система работает сама на себя — не по уму, а ради самосохранения.

Никто не спорит, в ряде случаев поиск по шаблону — вещь очень даже необходимая. Например, запросы SQL представляют собой чистой воды поиск по шаблону. И логично сочетаются с использованием регулярных выражений. В других системах управления базами данных есть свои языки построения шаблонов. Разумеется, это больше нужно администратору и программисту; рядовой пользователь разбираться с синтаксисом не станет, ему надо предложить набор специализированных форм поиска и фильтрации. Текстовые запросы пользователей — это всегда голые фрагменты текста, без каких-либо специальных символов. Обрабатывать такие запросы — дело прикладного программиста. Например, чтобы искать не только по ключевым словам, а еще и предлагать что-то весьма или отдаленно похожее. Конечно, в большинстве платформ есть встроенные средства ассоциативного поиска — и в регулярных выражениях соответствующий синтаксис имеется. Но на практике такие базовые средства почти всегда оказываются недостаточными или неуместными — и приходится изобретать свой велосипед для каждой конкретной задачи.

С точки зрения программиста — регулярные выражения тоже далеко не идеал. Компактность записи — пережиток первобытности. Сколько-нибудь сложные конструкции не всунешь в командную строку, в которой и так все слишком длинно, даже при активном употреблении алиасов, да еще и пайпить надо несколько раз... Файлы сценариев под Unix — минимальное обобщение командной строки, страдающее теми же недостатками. Вот и приходится жертвовать удобочитаемостью в угоду минимализму. Однако даже под Unix вполне допустимо вынести определение правил поиска в отдельный файл — и просто подгружать его при необходимости; при этом язык задания шаблона можно сделать вполне дружелюбным, с возможностью комментирования, с модульной организацией и сколь угодно развитыми средствами динамического формирования шаблонов и записи результатов в указанные каналы. В конце концов, и в стандарте регулярных выражений чистой декларативности никак не получается — а уж тем более в расширениях, используемых императивными языками типа Perl. Слышу возражения: развернутые сценарии поиска вредят эффективности. Но это уже зависит от интерпретатора, и со способом задания шаблонов никак не связано. Когда-то и регулярные выражения затыкались на сколько-нибудь нетривиальных задачах. Сейчас имеющиеся движки оптимизированы, и проблем почти нет. Минимализм как индивидуальный стиль — это нормально. Удобства в виде дырки в полу кого-то вполне устраивают. Но это не повод для отмены унитазов.

На практике сложные правила поиска практически никогда не нужны. И развитый синтаксис регулярных выражений — скорее помеха, чем подспорье. Если есть возможность обозримой визуализации результатов поиска — проще последовательно включать несколько фильтров, чем впихивать все сразу в один шаблон. Если такой возможности нет — претензии к используемой платформе.

Часто поиск по шаблону используется для массовой замены одного текста другим. Вот тут я, извините, не любитель. В крупных организациях, где сложились строгие стандарты записи конфигураций, это в какой-то мере может пригодиться. Но в реальной жизни стандартов мало кто придерживается, и массовые замены запросто могут погубить вполне работоспособную информационную сеть. Разнобой в данных — неизбежное зло. Поэтому мощные средства массовой обработки, вроде регулярных выражений, — это, как говорят в физике, превышение точности. Последовательные преобразования с контролем на каждом этапе — это спокойнее. Идеальный вариант — устранение самой необходимости массовых замен. Если что-то многократно повторяется, это свидетельство неэффективной организации данных. Правильно — когда каждый элемент данных задан один раз в одном месте. Тогда достаточно его поменять один раз — и все остальное получится автоматически. Касается это не только атомарных данных, но и форматов, и функциональности. Если меня не устраивает распределение доступов в системе, я должен иметь возможность задать где-то алгоритм — и не в скрюченном стиле регулярных выражений, а как полноценное описание функциональности. А дальше дело операционной системы разобраться с этим и применить. Очевидно, в масштабируемых системах потребуется иерархичность.

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

Не надо мне возражать — я ни с кем не спорю. Это мое личное мнение, на которое я, надеюсь, имею право — после десятков лет работы с компьютерным чем угодно. Да, в моей практике не было необходимости создавать высоконагруженные комплексы, в которых каждая микросекунда на счету. С другой стороны, есть подозрение, что чрезмерная нагрузка — результат неправильной организации, и следовало бы поискать что-то более эффективного, дабы потребности насиловать систему просто не возникало. Бывает, конечно, что пиковые нагрузки связаны с внешними обстоятельствами, с ажиотажным спросом на какой-нибудь ресурс, подобно атакам типа DDoS. Но в разумно организованной системе есть на тот случай адекватные технические решения (распределение нагрузки, ограничение доступа, оптимизация обслуживания запросов и т. д.) — если их почему-либо пока нет, то это надо делать. А не упиваться способностью пропустить через узкие ворота миллион дураков. Стоит ли идти на поводу у моды? Конечно, если речь идет только о том, чтобы деньги получить, — тогда без вопросов, выражайтесь в меру собственной испорченности. Но если мечтается создавать не только то, что продается, а еще и нечто разумное — другой разговор.


[Компьютеры] [Наука] [Унизм]