Pull to refresh

Comments 58

Как известно, на данный момент человечество алгоритмически реализовало только два смертных греха из семи: жадность и лень, остальные пять пока ожидают своего часа.

Хах, шикарно))

Один коллега мне на это ответил: "Чур, я реализую прелюбодеяние"

Оно опоздал, множественное наследование в С++ давно реализовано.

Если у вас была проблема и вы решили ее регуляркой, то теперь у вас 2 проблемы

+71<030003764014769+92165171<

Вместо одного или всех "+" может быть "-". По краям разделителей(+-<) могут быть(а могут не быть) пробелы. Надо найти строку целиком, а потом из неё выдернуть нужный кусок(в данном случае это "030003764014769").

Если выдернуть кусок можно накостылив поиски и реплейсы в строке(хотя с регуляркой это значительно проще), то первую часть я не вижу как реализовать без регулярки(область поиска - набор строк после OCR документа).

А ещё именно наличие регулярок(помимо прочего) делает сортировщик почты в TheBat! таким мощным инструментом(я бы сказал непревзойдённым, но сравнивать могу только с разными версиями Аутлук и с Тандербирд).

Мне кажется что вред от регулярок сильно переоценен. Просто для каждой ситуации надо адекватно оценивать насколько они тут нужны.

+71<030003764014769+92165171<

Вместо одного или всех "+" может быть "-". По краям разделителей(+-<) могут быть(а могут не быть) пробелы. Надо найти строку целиком, а потом из неё выдернуть нужный кусок(в данном случае это "030003764014769").

Не совсем понял задачу. Почему нужный кусок именно 030003764014769, а не 92165171 или 71 ?

Не могу точно сказать каков смысл у строки "+71<030003764014769+92165171< " целиком, но кусок который оттуда нужно достать - Payment Reference. И его нужно передать в информационную систему после распознания документа. Остальная часть строки не требуется, но т.к. формат(с учётом некоторого креатива от составителей счёта, в виде лишних пробелов и т.п.) строки стандартный, то его удобно искать по регулярке без указания области на листе для поиска, по крайней мере ложных срабатываний не встречалось ни разу.

\s*[-+]\s*\d+\s*[<]\s*(\d+)\s*[-+]\s*\d+\s*[<]\s*

типа такого?

Почти :). На данный момент все случаи покрывает такое выражение:

[+-]{1}N{1-2}[ ]{-}([^0123456789]{1-2}|"<")[ ]{-}N{10-}[ ]{-}"+"[ ]{-}N{5-}[ ]{-}"<"{-1}

P.S. Да, тут ещё и диалект свой используется, особенно в части "расширения".

* — Any character

O_o, японский бог, зачем?? У них там какие то особенные специалисты-мозголомы такой "диалект" придумывали

Трудно сказать зачем. Возможно пытались адаптировать под конкретную задачу - например, там есть "C" для заглавных букв, и "c" для всех(а ещё нечёткий поиск типа %DIGIT% для всего похожего на цифры). А может быть упрощали синтаксис для пользователей - хотя без кодинга там будет некомфортно(что-то с синтаксисом похожим на C#), но в принципе возможно.

Для меня главное неудобство в том что под такой синтаксис нет онлайн тестов как имеется под PCRE. А так уже привык, в принципе не так много регулярок приходится применять в реальной работе, и они в основном более чем просты для написания и чтения.


P.S. Сейчас обратил внимание что в первом наборе символов регулярки парсер хабра съел экранирование минуса, надо было вставлять как код однако...

Что такое регулярные выражения? Это измерительная рулетка, где вместо металлической ленты - резиновая. Растягивая такую рулетку можно "измерить" почти любой текст, подгоняя разметку под текст.

За что я не люблю регулярные выражения - так это за отсутствие единого стандарта. Для всего, что чуть сложнее "х?й", приходится читать мануал к данной конкретной программе и тщательно расставлять скобки, тильды, акценты, проценты и доллары.

Нет. В реальной жизни того, что рассмотрено тут более, чем достаточно. Ну ещё круглые скобки и их исключения (?:

Более того, в приличных местах за всё отличное от .?*^$[]|\s\S\d\D морды бьют. Мне на собесе как-то пытались дать задачу на именованные бэкреференсы, я им сказал, что мне (и компу) проще двумя простыми регекспами без извратов. А если такую хрень в коде встречу, то перепишу, чтобы второй раз не разбираться. Мне сказали, что принят)

А если такую хрень в коде встречу, то перепишу, чтобы второй раз не разбираться.

Так регекспы в принципе write only. Разбираться с ними - это все равно что старую изоленту аккуратно разматывать и переиспользовать. Проще намотать новую со свежего рулона.

Сложность разбора чужого регэкспа очень ситуативна.

Для примера, уралсибовский банкинг отказывался принимать мою почту из-за домена третьего уровня справа от @. Пока ждал ответа на запрос в саппорт решил слазить в потроха страницы. И вот как они проверяют валидность почты(к слову, занятие в принципе бесполезное):

/^[A-Za-z0-9!#$%&'*+=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+=?^_`{|}~-]+)*@(?:[A-Za-z0-9-]{1,63})+\.[A-Za-z]{2,63}$/

Лично мне потребовалось меньше минуты понять в чём тут косяк(помимо наличия подобной проверки в принципе), т.к. не было смысла вчитываться во всё выражение, зная что проблема в правой его части. Причём, с моей точки зрение, это именно баг - они точку не включили в группу, а без этого вообще я не вижу смысла в наличии тут группы с квантификатором.

К сожалению руки чесались проверить, исправил регулярку в инструментах разработчика, и добавил свой емейл в профиле. В результате саппорт читавший запрос по диагонали, и проигнорировавший дважды скриншот с проблемой, тупо сказал - "у вас в профиле указан ваш емейл, проблемы нет". Так что проблема так и не решена, хотя я им и регулярку их прислал, и написал что поправить чтобы работало. Сбер, к слову такую проблему признал, и пофиксил.

Зато теперь у вас есть прекрасный ответ на распространённый вопрос: "Ты ж программист. А можешь банк взломать?"

Нет. Читабельность регекспов, равно как читабельность любого другого кода. Если заморачиваться читабельностью и стараться сделать проще по коду, а не проще для себя, то вполне читаются. А сложные регэкспы и корявые, да. Если знаешь что должно, быть проще переписать, чем разбираться и ловить баги

Информативно, про жадность и лень хорошо объяснено

Например, выражение $однажды соответствует слову «однажды» только в начале строки

Опечатку нашёл. Не "$однажды", а "^однажды".

Да, такой вот я душный и нудный, если что читаю, то вычитываю побуквенно.

И не лень было тут коммент писать (выделять, делать цитату и т.д.)? Ведь можно выделить, нажать Ctrl+Enter и написать кратко - сообщение уйдёт в личку автору (куда в общем-то и надо про опечатки писать). Единственный кейс (как мне кажется), когда сюда писать про опечатки - когда нет клавиатуры (с телефона например), и искать как нажать Ctrl+Enter муторно или вообще нет возможности.

(да, в обществе зануд новый председатель :)

Ведь можно выделить, нажать Ctrl+Enter

А если с телефона?

Я же про это написал:

Единственный кейс (как мне кажется), когда сюда писать про опечатки - когда нет клавиатуры (с телефона например), и искать как нажать Ctrl+Enter муторно или вообще нет возможности.

Да и судя по тому, что там даже цитата вставлена, маловероятно, что тут с телефона. Ну да ладно, главное чтобы кто читает это увидел тоже.

Увидел, увидел. Но считаю что простые грамматические и/или орфографические опечатки да, надо отправлять именно автору через Ctrl-Enter, а на такие вот, которые могут запросто сбить с толку тех, кто регекспы увидел вообще впервые [в данном случае речь о регекспах], надо указывать открыто и прилюдно.

мне хватает автоматической замены на Хабре прямых кавычек " на типографские `«`

Есть еще один. Я как-то пытался отправить опечатку автору а мне: "Автор отключил возможность приема личных сообщений"

Спасибо за бдительность, исправили!

Разработчики делятся на три типа: те, кто уже понимает регулярные выражения и порой решает сложные задачи одной строкой; те, кто все еще боится их и всячески избегает; и те, кто уже прочитал первую часть этой серии статей и полон оптимизма разобраться с этими магическими письменами.

А ещё есть четвёртый тип, которые хвост и в гриву гоняли регулярки по поводу и без, ибо "красивое"..., но потом узнали, сколько ресурсов отжирает препроцессор регулярных выражений, и стали использовать их с большой осторожностью.

Просто "узнали" или столкнулись на практике? Уж очень сильно это "знание" смахивает на суеверие и преждевременную оптимизацию.

Про Catastrophic Backtracking есть множество статей на Хабре. Но это уже продвинутый уровень, нужно не просто разбираться в синтаксисе, но ещё как оно там всё работает внутри.

и те, кто уже прочитал первую часть этой серии статей и полон оптимизма

Ойвей, попался на эту удочку. Побежал перечитывать проект с подсветкой синтаксиса на регулярках.
Вернулся, чай пью. И без подсветки номально.

Отдельное спасибо за интонацию и забавные примеры, руны рождения и руны краха запоминаются легче)

"Регулярные выражения для Чайников"
Том 11

"...в заключение предисловия к введению в эту интереснейшую тему, предложу читателям 30% скидку на обслуживание в местной психиатрической клинике..."

P.S. Сори. Злоязычу :)

Столкнулся с тем, что часть выражений, которая валидна в regex101, не работает в гуглотаблицах.

А какой диалект выбираете в regex101?

Google Sheets использует движок RE2. Если я правильно понимаю, в regex101 он называется Golang.

$ — руна доллара, символизирует крах, тьму, конец строки.

Прям в точку своей актуальностью.

На заметку - выражение:
(^$\r\n)+

Позволяет в notepad++ найти и удалить все пустые строки

Только для CRLF (Windows) окончаний строк :)

Вы считаете, что надо разжевывать вплоть до того, что \r\n соответствуют CRLF?

А возможно кто-то не знает и что такое CRLF ;)

Намекает на существование юниксовых переносов и возможность обработать оба варианта. (^$\r?\n)+

Может быть не везде так, но обычно \r указывать на обязательно, \n сам подстраивается под кодировку.

Упс, вот здесь вы очень сильно нафантазировали. Попробуйте сформулировать какой-нибудь конкретный пример этого "обычно" и проверьте себя. Разумеется, ничего подобного вы не увидите.

Сейчас нет под рукой машины с виндой, поэтому проверить не могу. Но где-то что такое читал.

"\R matches any Unicode newline sequence", поддерживается только в диалектах PCRE и Java (среди диалектов на regex101).

А для Notepad++, вообще говоря, это было не нужно, в нём есть отдельная команда (Edit => Line Operations => Remove Empty Lines).

Для "обычного" поведения не нужно искать какую-то специальную программу, чтобы его продемонстрировать. Оно на то и обычное, что есть везде. Ну или наоборот - оно совсем даже необычное ;-)

Один из наиболее популярных, но опасных специальных символов — точка. ... такое регулярное выражение означает «что угодно сколько угодно раз»

И как пример .*

Извините, дальше читать не стал. Как-то меня выучили, что «что угодно сколько угодно раз» это всё-таки * а не точка. Наверное мои знания протухли.

В регулярках . - любой смвол, * - сколько угодно раз.

.* - любой символ сколько угодно раз.

Что не так? Или вы про маски в файлах?

Лучше написать "Соответственно, следующее регулярное выражение". В принципе там из контекста понятно, о чём речь, но слово "такое" действительно может относиться и туда и туда, а люди, увы, читают не глазами.

Перечитал этот абзац. Вы правы, не совсем понятно, про какое выражение речь.
Исправили.

Вот что значит писать комментарии ночью. Был не прав, приношу извинения.

Скорее, изначально были тухлыми. * - это "сколько угодно раз". А "что угодно сколько угодно раз" - это как раз .*. В статье всё написано правильно, а вот вы её читать перестали задолго до этого места, выхватив пару случайных фрагментов и перемешав их у себя в голове.

Когда-то давно тратил часы для бытовых задач (сложные групповые переименования), чтобы разобраться в этом адовом скпоплении символов. Как правило, безуспешно. И какая прекрасная эра наступила сейчас! Формулирую ИИ, вставляю какой-тоужасныйнаборнепонятночего в нужную программку - и всё, программка выдаёт нужный результат.

Если что, я, конечно, реально преклоняюсь перед теми, кто в этом как в воде. Но это надо иметь очень продвинутый мозг...

спасибо за обе статьи! получил удовольствие от стиля)

Я уже больше 20 лет в IT, и, конечно, регулярно появляются задачи, которые имеет смысл решать с помощью регулярных выражений. Я много раз разбирался с регулярками и столько же все обратно забывал. Сейчас мне проще Chat GPT попросить написать мне регулярку, чем заново все вспоминать. Кстати, способность мозга забывать - весьма недооцененная фича, на мой взгляд. Наш природный Garbage Collector позволяет избавляться от мусора, сохранять мозги в тонусе и поддерживать необходимый уровень нейропластичности для адаптации к меняющимся условиям. И так получилось, что для меня регулярки стали таким "мусором". А еще, регулярки часто работают медленнее чем алгоритмический разбор строки. Но иногда, да, на регулярках получается красиво.

  1. Если используется реализация на Java, то фильтровать символы кириллицы можно выражением \p{InCyrillic} (там есть имена и для других письменностей).

  2. Есть не только жадные и ленивые, существует три категории: Greedy, Reluctant и Possessive, там уже тонкости.

Sign up to leave a comment.