<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>Регулярные выражения</title>
    <description/>
    <link>https://tproger.ru/tag/regexp</link>
    <atom:link href="https://tproger.ru/tag/regexp/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Fri, 09 Oct 2026 13:25:28 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Регулярные выражения</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</title>
      <link>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</link>
      <comments>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</guid>
      <description><![CDATA[<p>Семь советов для ускорения работы в терминале Linux. Как быстро обработать файлы, отладить Bash-скрипт и редактировать длинные пути в Линукс.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni">Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 22 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Сколько статей про «полезные команды Linux» вы уже прочитали?</b> Алиасы, history, базовые горячие клавиши — факты для джунов, которые опытным админам уже снятся. Если свободно пользуетесь grep и awk, создаете циклы, применяете регулярные выражения — эта статья для вас.</p><p>Рассказываем про 7 команд, влияющие на скорость работы в терминале. Вы узнаете:</p><ul><li>про встроенные bash-операции, которые заменяют пайплайны,</li><li>про способы работы с файловыми дескрипторами,</li><li>про wildcards, которые избавляют от сложных конструкций с find.</li></ul><p>Каждая команда в подборке решает конкретную проблему:</p><ul><li>массовая обработка файлов,</li><li>отладка скриптов,</li><li>работа с длинными путями.</li></ul><h2>1. Bash variable expansions</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/b5f2b475-b18e-49cb-a00c-9197ab87b9f4.jpg" alt="" /></figure><p>Вместо <i>basename</i>, <i>cut </i>для простых операций со строками можно использовать встроенные возможности Bash:</p><p><b>%</b> режет справа до первого совпадения, <b>%%</b> — до последнего. Символ <b>#</b> работает слева направо.</p><p>В реальной работе это помогает при массовой обработке файлов. Например, есть 1000 логов, и нужно каждый переименовать.</p><p>Если использовать <i>basename</i>, запустится 1000 отдельных процессов. <b>Variable expansions</b> работают без <i>fork/exec</i>, без задержек на создание процессов.</p><p>Bash variable expansions используют в циклах с файлами и при работе с массивами. Когда скрипт обрабатывает сотни файлов, разница в скорости становится заметной. Еще и код выглядит чище.</p><h2>2. Here-string (&lt;&lt;&lt;)</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/ef72e05d-6f80-49aa-842b-32c209d8b724.jpg" alt="" /></figure><p>Here-string упрощает передачу строковых данных в команды без создания временных файлов или использования echo с пайпом.</p><p>Реальная экономия времени проявляется при отладке и модификации скриптов. Например, когда SQL-запрос или конфигурация зашиты в <i>here-документ</i>. С <b>here-string </b>данные собраны в одном месте, легко редактируются и переиспользуются.</p><p>Работает не только с базами данных. Отправка в API, конфигурирование сетевых устройств через expect, передача команд в Docker — через &lt;&lt;&lt; код будет понятнее, а сопровождение проще.</p><h2>3. /proc/$$/fd</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/f314de69-9459-4ecb-ab62-2c7b5c7b54f3.jpg" alt="" /></figure><p>Каждый процесс имеет стандартные дескрипторы <b>0</b> (stdin), <b>1</b> (stdout), <b>2</b> (stderr), которые представлены как символические ссылки. Директория <b>/proc/$$/fd </b>предоставляет доступ к файловым дескрипторам текущего процесса:</p><p>Переменная <b>$$</b> содержит PID текущего процесса, поэтому /proc/$$/fd ведет к дескрипторам именно вашего шелла.</p><p>Практическое применение — отладка перенаправлений и работа с дескрипторами в сложных скриптах:</p><h2>4. Wildcards с диапазонами</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/08dbc2a0-5e2e-49a3-9486-a042a0480369.jpg" alt="" /></figure><p>Про <b>*</b> и <b>?</b> говорят чаще, чем про диапазоны в квадратных скобках. Такие маски используют реже, а зря — они решают массу задач по отбору файлов.</p><p>Wildcards автоматически раскрываются шеллом в список подходящих файлов — это их основная функция. Кавычки нужны только когда передаете символы [, ] как литеральные:</p><p>Экономия времени заметна при работе с логами, бэкапами и в скриптах автоматизации. Например, для архивации файлов с определенными номерами, очистки временных файлов с нужными паттернами.</p><h2>5. sudo !!</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/9434c945-925f-40b3-9062-994fce2091c6.jpg" alt="" /></figure><p>Набрали длинную команду, нажали Enter, получили «<b>Permission denied</b>». Рука на рефлексе тянется к стрелке вверх и Home, чтобы добавить sudo в начало.</p><p>Вот способ в разы быстрее:</p><p>Двойное восклицание <b>!!</b> — это ссылка на предыдущую команду целиком. Bash подставит всю строку со всеми аргументами и ключами. Кажется мелочью, но для админа, который 10 раз в день забывает sudo, это серьезная оптимизация.</p><p>Двойное восклицание универсально и работает не только с sudo:</p><ul><li><b>time !!</b> для замера времени выполнения,</li><li><b>nohup !! &amp;</b> для запуска в фоне,</li><li><b>strace !!</b> для отладки.</li></ul><p>Если между командой и sudo !! выполнялись другие команды, восклицание сработает для последней из них. Для поиска конкретной команды в истории используйте <b>!строка</b>.</p><h2>6. ^старое^новое</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/1888b625-8ae5-4d0e-a73d-25260ff7d893.jpg" alt="" /></figure><p>Основной способ исправления опечатки — стрелка вверх, поиск ошибки, исправление. Смотрите, как можно сделать это побыстрее:</p><p>Символ <b>^</b> ищет первое вхождение слова и заменяет его. Работает с последней командой.</p><p>Заменяется только первое вхождение. Если ошибочное слово встречается несколько раз, способ не сработает. В таких случаях придется использовать классическое редактирование или <i>history expansion</i>.</p><h2>7. Alt+.</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/4d1c03bb-66b2-4cb0-8c3e-ce80c3406ec5.jpg" alt="" /></figure><p>Создали файл с длинным именем — теперь его нужно отредактировать, переместить, изменить права. Каждый раз перепечатывать путь утомительно и чревато ошибками.</p><p>Комбинация <b>Alt+.</b> (Alt + точка) вставляет последний аргумент предыдущей команды в текущую позицию курсора. Повторное нажатие перебирает аргументы из более ранних команд.</p><p>Экономия времени проявляется при работе с файлами и директориями. Например: распаковали архив, теперь нужно зайти в созданную папку, затем посмотреть содержимое, потом изменить права. Вместо того, чтобы 3 раза печатать один путь, можно 3 раза нажать Alt+.</p><p>Еще этой комбинацией вставляются:</p><ul><li>имена пользователей,</li><li>IP-адреса,</li><li>названия сервисов,</li><li>параметры конфигурации.</li></ul><p>Alt + точка работает в большинстве шеллов. Привыкнув к ней, начинаешь использовать на автомате.</p><h2>Что запомнить</h2><ul><li><b>${filename%.*} </b>и встроенные операции со строками работают быстрее внешних утилит. % режет справа, # — слева. Полезно при работе с циклами для массовой обработки файлов.</li><li><b>&lt;&lt;&lt;</b> — here-string удобен для передачи коротких строковых данных в команды. С многострочными данными лучше использовать here-document или переменные.</li><li><b>/proc/$$/fd</b> — доступ к файловым дескрипторам текущего процесса. Ускоряет отладку перенаправлений и работу с дескрипторами.</li><li><b>file[1-5] и [^b]* </b>— диапазоны в wildcards для точного отбора файлов. Кавычки нужны только для передачи литеральных символов.</li><li><b>sudo !!</b> — повторяет последнюю команду с sudo. Также работает с time !!, nohup !! &amp;. Если между нужной командой и !! выполнялись другие операции, используйте !строка для поиска конкретной команды в истории.</li><li><b>^старое^новое</b> — заменяет первое вхождение в предыдущей команде. Работает только с последней командой и заменяет первое совпадение.</li><li><b>Alt+. </b>— вставляет последний аргумент предыдущей команды. Повторное нажатие перебирает аргументы из истории команд. Экономит время при работе с длинными путями.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>JavaScript: большой гайд от Tproger</title>
      <link>https://tproger.ru/articles/javascript--bolwoj-gajd-ot-tproger</link>
      <comments>https://tproger.ru/articles/javascript--bolwoj-gajd-ot-tproger?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/javascript--bolwoj-gajd-ot-tproger</guid>
      <description><![CDATA[<p>Гайд по JavaScript. Топовые и полезные статьи с теорией, инструментами и фреймворками. Практика для новичков и продвинутых программистов.  ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/javascript--bolwoj-gajd-ot-tproger">JavaScript: большой гайд от Tproger</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Безопасный код]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 08 May 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>JavaScript — база веб-разработки. На нем пишут интерактивные веб-интерфейсы, динамичные приложения и серверные фичи. В общем, на JS можно делать все — от простых скриптов до сложных экосистем. В этом гайде собрали статьи для новичков и не только, которые помогут прокачаться в JavaScript.</p><h2>База и теория</h2><ol><li><a href="https://tproger.ru/articles/event-loop-dlya-chajnikov--prostymi-slovami-o-slozhnom-mehanizme-brauzera">Event loop для чайников: простыми словами о сложном механизме браузера</a> — В статье разбираем, что такое Event Loop, очередь задач и стек вызовов. Простыми словами о том, как браузер выполняет JavaScript-код и обрабатывает события.</li><li><a href="https://tproger.ru/articles/chek-list-dlya-node-js-novichkov--obrabotka-owibok-254149">Чек-лист по Node.js для новичков: обработка ошибок</a> — Показываем основные подходы к обработке ошибок для Node.js. Рассматриваем пошаговую инструкцию и практические примеры.</li><li><a href="https://tproger.ru/articles/znaniya--kotorymi-dolzhen-obladat-javasript-razrabotchik-v-2024-godu--eto---baza">Что нужно учить JavaSript-разработчикам в 2024 году</a> — Разбираем, какие технологии и навыки нужно знать JS-разработчику, в том числе и в 2025. От фреймворков до подходов к архитектуре.</li><li><a href="https://tproger.ru/articles/deklarativnyj-javascript">Декларативные языки на примерах с JavaScript</a> — Рассказываем, что значит декларативный стиль программирования. Сравниваем с императивным на примерах JavaScript.</li><li><a href="https://tproger.ru/articles/javascript-localstorage-polnoe-rukovodstvo">JavaScript localStorage: Полное руководство</a> — Разбираем, как работает localStorage. Учим сохранять данные на клиенте с помощью JavaScript.</li><li><a href="https://tproger.ru/articles/ponimanie-strogogo-rezhima-javascript">Как работает режим strict в JavaScript</a> — Объясняем, что делает режим strict и почему он помогает писать более безопасный код на JavaScript.</li><li><a href="https://tproger.ru/articles/kak-besplatno-vyuchit-javascript-i-ne-idti-v-onlajn-wkoly">Как бесплатно выучить JavaScript и не идти в онлайн-школы</a> — Рассказываем, как самостоятельно освоить JavaScript. Бесплатные ресурсы, полезные советы и личный план обучения.</li><li><a href="https://tproger.ru/articles/kakie-js-biblioteki-ispolzovat-dlya-animacij-na-sajte-v-2024-godu">Какие JS-библиотеки использовать для анимаций на сайте в 2024 году</a> — Актуальные JavaScript-библиотеки для веб-анимации. Рассматриваем лучшие инструменты для красивых и быстрых интерфейсов.</li></ol><h2>Практикуемся</h2><ol><li><a href="https://tproger.ru/articles/10-realnyh-voprosov-s-sobesedovaniya-javascript-razrabotchika-s-otvetami-254156">10 реальных вопросов с собеседования JavaScript-разработчика с ответами</a> — Подборка реальных вопросов с собеседований для JavaScript-разработчиков. Даем ответы и объясняем, как правильно мыслить на интервью.</li><li><a href="https://tproger.ru/articles/prilozhenie-dlya-prognoza-pogody-na-vue-js">Приложение прогноза погоды с использованием Vue JS</a> — Пошаговое руководство по созданию погодного приложения на Vue.js. Обучаем взаимодействию с API и построению интерфейса.</li><li><a href="https://tproger.ru/articles/10-legendarnyh-uravnenij-na-javascript">Математика в программировании: реализуем уравнения на JavaScript</a> — Объясняем, как реализовать математические уравнения на JavaScript. Практика для программистов, которые не боятся формул.</li><li><a href="https://tproger.ru/articles/regulyarnye-vyrazheniya-v-javascript-eto-ne-tak-strawno-kak-vy-dumaete">Регулярные выражения в JavaScript: разбираемся в создании</a> — Учим создавать и использовать RegExp в JavaScript. Поясняем синтаксис, паттерны и типовые ошибки.</li><li><a href="https://tproger.ru/articles/reshaem-populjarnye-zadachi-s-asinhronnym-kodom-na-javascript-chast-pervaja">Решаем популярные задачи с асинхронным кодом на JavaScript: часть первая</a> — Практика асинхронного программирования на JavaScript. Решаем задачи с API, задержками и промисами.</li><li><a href="https://tproger.ru/articles/tutorial-po-javascript-async-x2f-await-izuchaem-callbacks-promises-i-async-x2f-await">Асинхронный JavaScript: изучаем Async/Await, Callbacks и Promises</a> — Учим писать асинхронный код в JavaScript: от колбэков до современного async/await. Понятно, на примерах и без лишнего.</li><li><a href="https://tproger.ru/articles/reshaem-populjarnye-zadachi-s-asinhronnym-kodom-na-javascript-chast-vtoraja">Задачи по асинхронному программированию на JS</a> — Упражнения на асинхронный JavaScript. От простых примеров до сложных сценариев.</li></ol><p>Предыдущие подборки лежат здесь: <a href="https://tproger.ru/articles/bolwoj-gajd-po-react-ot-tproger--topovye-stati-i-instrumenty">React</a>, <a href="https://tproger.ru/articles/bolwoj-gajd-po-mobilnoj-razrabotke-ot-tproger--poleznye-stati--praktiki-i-sovety">мобильная разработка</a>, <a href="https://tproger.ru/articles/s----vse-samye-vazhnye-materialy-ot-tproger">С++</a>, <a href="https://tproger.ru/articles/bolwoj-gajd-po-instrumentam-dlya-razrabotchikov-ot-tproger--frejmvorki--bazy--ai-i-devops-v-odnoj-podborke">инструменты</a>.</p><p>Кстати! Забрать все самые топовые нейронки для айтишников можно в нашем <a href="https://tprg.ru/LN8a">большом гайде с 70+ ИИ-инструментами </a></p>]]></content:encoded>
    </item>
    <item>
      <title>Регулярные выражения в JavaScript: это не так страшно, как вы думаете</title>
      <link>https://tproger.ru/articles/regulyarnye-vyrazheniya-v-javascript-eto-ne-tak-strawno-kak-vy-dumaete</link>
      <comments>https://tproger.ru/articles/regulyarnye-vyrazheniya-v-javascript-eto-ne-tak-strawno-kak-vy-dumaete?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[МТС]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/regulyarnye-vyrazheniya-v-javascript-eto-ne-tak-strawno-kak-vy-dumaete</guid>
      <description><![CDATA[<p>Подробный гайд с примерами по регулярным выражениям в JS, позволяющим выполнять любые манипуляции со строками.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/regulyarnye-vyrazheniya-v-javascript-eto-ne-tak-strawno-kak-vy-dumaete">Регулярные выражения в JavaScript: это не так страшно, как вы думаете</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Для продолжающих]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 20 Apr 2023 10:14:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Регулярные выражения — тема, которой боятся многие разработчики. Между тем они требуются в большинстве вакансий уровня middle. В статье разберём основные символы и способы создания регулярных выражений в JavaScript, которые с небольшими отличиями работают и в других языках программирования.</p><p>Рассмотрим тему регулярных выражений от простого к сложному.</p><h2>Что такое регулярные выражения</h2><p>Регулярные выражения (ещё их называют Regular Expressions, сокращённо regex или regexp, регулярки) — специальные шаблоны, которые используют для поиска и обработки текста. Для поиска в них можно задавать дополнительные команды, например игнорирование регистра.</p><p>В отличие от обычных функций поиска и замены, которые встречаются во всех текстовых редакторах, регулярные выражения могут сочетаться с другим кодом. С их помощью можно выполнять сложные операции с текстом, менять порядок строк, извлекать отдельные слова, валидировать и передавать информацию на сервер.</p><p>А ещё регулярки экономят очень много кода. Но есть один недостаток — они часто выглядят пугающе, запутанно и странно, особенно если шаблон сложный.</p><p><b>Например, этот шаблон ищет email-адреса:</b></p><p>/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ </p><p>Почти во всех языках программирования есть регулярные выражения — реализация может отличаться, но основные моменты похожи. Их можно сравнить с отдельным мини-языком, который функционирует сам по себе.</p><p>Интересный момент: регулярные выражения действительно сложно писать, сложно читать и сложно поддерживать или изменять, но часто именно с их помощью разумнее выполнять работу над строками.</p><p><b>Например, нам нужно проверить номер телефона в форме регистрации:</b></p><p>В этом примере мы создали функцию validatePhoneNumber, которая принимает номер телефона в качестве аргумента и возвращает true, если номер телефона является действительным номером для России, и false в противном случае.</p><p>В регулярном выражении phoneRegex мы использовали символ ^, чтобы указать, что номер телефона должен начинаться с «+7» или «8» (возможно, без плюса). Затем мы использовали символы \d для указания цифр и {10} для указания количества цифр в номере телефона (10 цифр).</p><p>В примере использования мы передали строку «+79123456789» функции validatePhoneNumber и проверили результат.</p><h2>Как создать регулярное выражение в JavaScript</h2><p>Есть два способа создания регулярок — разберём каждый.</p><h3>1. Конструктор RegExp()</h3><p>Конструктор RegExp() позволяет создавать регулярные выражения на основе строки, передаваемой ему в качестве аргумента. Формат конструктора RegExp() выглядит следующим образом:</p><p>const regex = new RegExp("pattern", "flags");</p><p>Где «pattern» — это строка, содержащая регулярное выражение, а «flags» — дополнительные флаги, определяющие, как будет работать регулярное выражение. Например, флаг i указывает, что регулярное выражение должно игнорировать регистр символов.</p><p>Вот пример использования конструктора RegExp() для создания регулярного выражения, которое ищет все цифры в строке:</p><p>const regex = new RegExp("\\d", "g");</p><p>Здесь мы передаём строку \d в качестве первого аргумента, что означает «любая цифра». Флаг g указывает, что регулярное выражение должно искать все совпадения в строке.</p><p>Этот способ предпочтительнее, когда вы знаете, что выражение будет изменяться или вы не знаете шаблон. Например, это информация, которую вводит пользователь в формах.</p><h3>2. Литералы</h3><p>Литерал регулярного выражения, так же как и конструктор, состоит из двух частей. Первая часть — шаблон, который необходимо описать, он заключается в слеши (//). Вторая часть, после закрывающего слеша, — флаги, но их использование также необязательно.</p><p>Вот как он выглядит:</p><p>const regex = /pattern/flags;</p><p>Разберём на примере использования литерала для создания того же регулярного выражения, которое ищет все цифры в строке:</p><p>const regex = /\d/g;</p><p>Здесь мы используем литерал /\d/g, который означает «любая цифра» с флагом g, указывающим, что регулярное выражение должно искать все совпадения в строке.</p><p>Обратите внимание: если вы планируете создавать регулярные выражения при помощи литералов, такой подход не позволяет изменять задаваемые значения динамически — литералы регулярных выражений компилируются заранее при анализе скрипта. Зато если ваше регулярное выражение постоянно, то литералы позволяют увеличить производительность.</p><p>Оба эти способа создания регулярных выражений в JavaScript эквивалентны друг другу — выбирайте тот, который вам удобнее.</p><h2>Базовый синтаксис регулярных выражений в JavaScript</h2><p>Разберём основу синтаксиса регулярных выражений в JavaScript.</p><h3>Шаблоны и метасимволы</h3><p>Шаблоны — набор символов, которые используют для поиска определённых сочетаний символов в тексте. Метасимволы — специальные символы, которые используют для составления шаблонов.</p><p><b>Вот несколько примеров шаблонов и метасимволов:</b></p><p>. — соответствует любому одиночному символу, кроме символа новой строки.</p><p>* — соответствует нулю или более повторениям предыдущего символа.</p><p>+ — соответствует одному или более повторениям предыдущего символа.</p><p>? — соответствует нулю или одному повторению предыдущего символа.</p><p>^ — соответствует началу строки.</p><p>$ — соответствует концу строки.</p><p>() — определяет группу символов, которые могут быть повторены.</p><h3>Квантификаторы и модификаторы</h3><p><b>Квантификаторы</b> — метасимволы, которые определяют количество повторений предыдущего символа.</p><p><b>Некоторые квантификаторы:</b></p><p>{n} — соответствует ровно n повторениям предыдущего символа.</p><p>{n,m} — соответствует от n до m повторений предыдущего символа.</p><p>{n,} — соответствует n или более повторениям предыдущего символа.</p><p>? — делает предыдущий квантификатор ленивым, т. е. соответствует наименьшему возможному количеству повторений.</p><p>Пример использования квантификатора:</p><p>const pattern = /a{3}/; // соответствует трём символам "a" подряд</p><p>В тексте, который будет обрабатываться с помощью этого регулярного выражения, будут найдены все вхождения трёх символов a подряд. Например, строка «baaaad» будет соответствовать шаблону, а строка «abaa» — нет.</p><p>Модификаторы — специальные флаги, которые можно добавить к регулярному выражению для изменения его поведения.</p><p>Некоторые модификаторы:</p><p>g — глобальный поиск, ищет все совпадения в строке.</p><p>i — игнорирование регистра, игнорирует различия между верхним и нижним регистром.</p><p>m — многострочный поиск, позволяет искать совпадения в нескольких строках.</p><p>Пример использования модификатора:</p><p>const pattern = /test/gi; // соответствует строкам "test" или "Test" или "TEST" глобально и без учёта регистра</p><h3>Группы и обратные ссылки</h3><p>Группы — последовательности символов, заключённые в скобки (), которые могут повторяться с помощью квантификаторов. Группы также позволяют использовать обратные ссылки, которые ссылаются на результат совпадения группы в регулярном выражении. Обратная ссылка обозначается символом \ и номером группы, например, \1 ссылается на первую группу.</p><p>Пример использования групп и обратных ссылок:</p><p>​​const pattern = /(\w+)\s\1/; // соответствует повторяющейся последовательности символов, разделённой пробелом</p><p>В этом примере группа (\w+) соответствует любой последовательности символов, состоящей из буквенно-цифровых символов и подчёркивания. Затем \s соответствует пробелу, а \1 обратно ссылается на первую группу (\w+), так что регулярное выражение соответствует только тем строкам, в которых последовательность символов повторяется через пробел.</p><h2>Экранирование в регулярных выражениях</h2><p>Как мы разобрались выше, в регулярках есть символы, которые имеют специальное значение и используются для обозначения шаблонов, таких как поиск символов, чисел и т. д. Но иногда возникают ситуации, когда эти символы должны быть экранированы — использованы как обычные символы, вместо своего специального значения.</p><p>Для экранирования символа используется обратный слеш \.</p><p>Например, символ . в регулярном выражении означает любой символ, но если мы хотим использовать точку как обычный символ, мы можем экранировать его, написав \.</p><p><b>Примеры:</b></p><ul><li>Поиск всех цифр в тексте.</li></ul><ul><li>Замена всех пробелов на символ подчёркивания.</li></ul><ul><li>Замена всех точек в тексте на запятые, кроме точек, которые находятся внутри чисел.</li></ul><h2>Как использовать регулярки с методами объекта RegExp и String</h2><p>После того как базовый синтаксис и способы написания шаблонов усвоены, перейдём к использованию регулярок в работе. Для работы с регулярными выражениями в JavaScript есть несколько методов — рассмотрим каждый.</p><h3>Метод test()</h3><p>Метод test() проверяет, соответствует ли регулярное выражение заданной строке. Метод возвращает true, если строка соответствует регулярному выражению, и false, если не соответствует.</p><p>Пример использования метода test():</p><p>В этом примере мы используем метод test() для проверки, содержит ли строка str подстроку «Hello». Регулярное выражение /Hello/ соответствует строке «Hello», и метод test() вернёт true.</p><h3>Метод exec()</h3><p>Метод exec() используется для поиска совпадений регулярного выражения в заданной строке. Метод возвращает массив, содержащий найденное совпадение и дополнительную информацию о нём.</p><p>Пример использования метода exec():</p><p>В этом примере мы используем метод exec() для поиска совпадений регулярного выражения /Hello/ в строке str. Метод exec() возвращает массив, содержащий найденное совпадение «Hello», индекс первого символа совпадения в исходной строке и саму исходную строку.</p><h3>Метод match()</h3><p>Метод match() используется для поиска всех совпадений регулярного выражения в заданной строке. Метод возвращает массив, содержащий все найденные совпадения.</p><p>Пример использования метода match():</p><p>В этом примере мы используем метод match() для поиска всех совпадений регулярного выражения /the/gi в строке str. Метод match() возвращает массив, содержащий все найденные совпадения, включая повторения.</p><h3>Метод replace()</h3><p>Метод replace() принимает два аргумента: регулярное выражение и строку, на которую нужно заменить найденное совпадение. Этот метод ищет все совпадения с заданным регулярным выражением в исходной строке и заменяет их на указанную строку.</p><p>Пример использования метода replace():</p><p>В этом примере мы используем метод replace() для замены слова «мир» на «земля» в строке «Привет, мир!» Регулярное выражение /мир/ ищет все совпадения со словом «мир» в строке, и метод replace() заменяет их на слово «земля». Результатом работы метода является новая строка «Привет, земля!»</p><h3>Метод search()</h3><p>Метод search() принимает один аргумент — регулярное выражение. Он ищет первое совпадение с заданным регулярным выражением в исходной строке и возвращает индекс первого символа совпадения. Если совпадение не найдено, метод возвращает -1.</p><p>Например:</p><p>В этом примере мы используем метод search() для поиска первого совпадения со словом «текст» в строке «Это текст для примера». Регулярное выражение /текст/ ищет первое совпадение со словом «текст» в строке, и метод search() возвращает индекс первого символа этого совпадения, который равен 4.</p><h3>Метод split()</h3><p>Метод split() принимает один аргумент — регулярное выражение. Он разбивает исходную строку на массив подстрок, используя заданное регулярное выражение как разделитель.</p><p>Пример использования метода split():</p><p>В этом примере мы используем метод split() для разделения строки «Это текст для примера» на массив слов, используя регулярное выражение / / в качестве разделителя. Регулярное выражение / / ищет все пробелы в строке, и метод split() использует их в качестве разделителя для разделения строки на массив слов. Результатом работы метода является массив [«Это», «текст», «для», «примера»].</p><h2>Когда и как использовать регулярки на практике</h2><p>Регулярные выражения пригодятся для самых разных задач: поиска текста, валидации данных, замены текста, разбора текста на составляющие, генерации паролей и т. д.</p><p>Разберём подробнее несколько вариантов использования.</p><h3>Валидация email-адресов</h3><p>Один из популярных примеров использования регулярных выражений — валидация email-адресов.</p><p><b>Шаблон будет выглядеть так:</b></p><p>/^[^\s@]+@[^\s@]+\.[^\s@]+$/, где</p><p>^ — начало строки</p><p>@ — символ «@»</p><p>\. — символ «.» (экранированный с помощью слеша)</p><p>$ — конец строки</p><p>Таким образом, этот паттерн соответствует любому email-адресу, который состоит из локальной части (часть до символа «@») и доменной части (часть после символа «@» и до символа «.») с верным форматом.</p><p>Для проверки email-адреса на соответствие шаблону можно использовать метод test():</p><p>В этом примере функция validateEmail() принимает email-адрес в качестве аргумента и использует регулярное выражение для проверки его соответствия формату. Метод test() возвращает true, если email-адрес соответствует паттерну, и false в противном случае.</p><h3>Форматирование текста</h3><p>Регулярные выражения могут быть полезны для форматирования текста, например для замены повторяющихся символов, форматирования дат и т. д.</p><p>Рассмотрим пример форматирования даты с использованием регулярных выражений.</p><p>Допустим, у нас есть дата в формате «гггг-мм-дд» (например, «2023-03-29»), а мы хотим преобразовать её в формат «дд.мм.гггг» (например, «29.03.2023»). Для этого мы можем использовать регулярное выражение, чтобы разделить дату на отдельные части, а затем использовать эти части для создания новой строки в нужном формате.</p><p><b>Давайте разберём это регулярное выражение:</b></p><p>^ — начало строки</p><p>(\d{4}) — группа, соответствующая 4 цифрам (год)</p><p>— — символ «-«</p><p>(\d{2}) — группа, соответствующая 2 цифрам (месяц)</p><p>— — символ «-«</p><p>(\d{2}) — группа, соответствующая 2 цифрам (день)</p><p>$ — конец строки</p><p>В этом примере мы используем метод match() для поиска соответствия регулярному выражению в строке date. Если соответствие найдено, метод match() возвращает массив, содержащий соответствующие группы в порядке их появления в регулярном выражении. Затем мы используем эти группы для создания новой строки в нужном формате.</p><p>Регулярные выражения также могут быть полезны для форматирования других типов данных, например, для замены повторяющихся символов или форматирования номеров телефонов.</p><h3>Извлечение номеров телефонов из строки</h3><p>Регулярные выражения широко используются для извлечения информации из текстовых строк. Например, если есть строка, содержащая номера телефонов, можно использовать регулярные выражения, чтобы извлечь эти номера телефонов и сохранить их в базе данных.</p><p>Рассмотрим несколько примеров использования регулярных выражений для извлечения информации из строк.</p><p>Допустим, у вас есть строка, содержащая несколько номеров телефонов. Вы хотите извлечь эти номера телефонов из строки и сохранить их в базе данных.</p><p>Для этого вы можете использовать следующий код:</p><p>В этом примере мы используем регулярное выражение<b> </b>/\+\d\s?\(\d{3}\)\s?\d{3}-\d{2}-\d{2}/g, чтобы извлечь номера телефонов из строки string.</p><p>Регулярное выражение ищет символ «+», и за ним следует одна или несколько цифр, за которыми следует необязательный пробел. Затем идут открывающая и закрывающая скобки, за которыми следуют три цифры, после чего снова идёт необязательный пробел. Далее идут три цифры, тире, две цифры, тире и ещё две цифры. В результате, если в строке есть номер телефона в формате, соответствующем регулярному выражению, он будет извлечён и сохранён в массиве phoneNumbers.</p><h2>Ещё несколько советов по использованию регулярок</h2><ul><li>Пишите максимально простые регулярные выражения и не усложняйте код без необходимости. Чем проще регулярное выражение, тем быстрее и эффективнее оно будет работать.</li></ul><ul><li>Тестируйте регулярные выражения перед использованием. Это позволит выявить возможные ошибки или проблемы в выражении и сделать необходимые исправления. Используйте онлайн-сервисы, такие как regex101.com, regexr.com, regexplanet.com и подобные.</li><li>Не злоупотребляйте использованием регулярок. Иногда другие простые методы могут оказаться более эффективными и лёгкими в понимании.</li></ul><ul><li>Используйте комментарии и форматирование кода, чтобы облегчить его чтение и обслуживание. Регулярные выражения могут быть очень сложными для понимания.</li><li>Используйте библиотеки. Есть множество библиотек уже готовых шаблонов — часто этого достаточно для решения задачи.</li></ul><h2>Заключение</h2><p>Мы разобрали основные моменты и области применения регулярок. Надеемся, что гайд поможет упростить работу, перестать бояться сложных на вид шаблонов и решать с их помощью даже самые нетривиальные задачи.</p>]]></content:encoded>
    </item>
    <item>
      <title>Java RegEx: использование регулярных выражений на практике</title>
      <link>https://tproger.ru/articles/java-regex-ispolzovanie-reguljarnyh-vyrazhenij-na-praktike</link>
      <comments>https://tproger.ru/articles/java-regex-ispolzovanie-reguljarnyh-vyrazhenij-na-praktike?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/java-regex-ispolzovanie-reguljarnyh-vyrazhenij-na-praktike</guid>
      <description><![CDATA[<p>Рассмотрим регулярные выражения в Java с учётом особенностей языка и с практическим применением для решения нескольких задач.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/java-regex-ispolzovanie-reguljarnyh-vyrazhenij-na-praktike">Java RegEx: использование регулярных выражений на практике</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 02 Sep 2021 10:55:19 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассмотрим регулярные выражения в Java, затронув синтаксис и наиболее популярные конструкции, а также продемонстрируем работу RegEx на примерах.</p><ol><li><a href="https://tproger.ru/#part0">Основы регулярных выражений</a></li><li><a href="https://tproger.ru/#part1">Регулярные выражения в Java</a></li><li><a href="https://tproger.ru/#part2">Примеры использования регулярных выражений в Java</a></li></ol><h2>Основы регулярных выражений</h2><p>Мы подробно разобрали базис в статье <a href="https://tproger.ru/articles/regexp-for-beginners/">Регулярные выражения для новичков</a>, поэтому здесь пробежимся по основам лишь вскользь.</p><h3>Определение</h3><p>Регулярные выражения представляют собой формальный язык поиска и редактирования подстрок в тексте. Допустим, нужно проверить на валидность e-mail адрес. Это проверка на наличие имени адреса, символа @, домена, точки после него и доменной зоны.</p><p>Вот самая простая регулярка для такой проверки:</p><p>В коде регулярные выражения обычно обозначается как regex, regexp или RE.</p><h3>Синтаксис RegEx</h3><p>Символы могут быть буквами, цифрами и метасимволами, которые задают шаблон:</p><figure><img src="https://media.tproger.ru/uploads/2021/09/image-3.png" alt="" /></figure><p>Есть и другие конструкции, с помощью которых можно сокращать регулярки:</p><ul><li><b>\d</b> — соответствует любой одной цифре и заменяет собой выражение [0-9];</li><li><b>\D</b> — исключает все цифры и заменяет [^0-9];</li><li><b>\w</b> — заменяет любую цифру, букву, а также знак нижнего подчёркивания;</li><li><b>\W</b> — любой символ кроме латиницы, цифр или нижнего подчёркивания;</li><li><b>\s</b> — поиск символов пробела;</li><li><b>\S</b> — поиск любого непробельного символа.</li></ul><h3>Квантификаторы</h3><p>Это специальные ограничители, с помощью которых определяется частота появления элемента — символа, группы символов, etc:</p><ul><li>? — делает символ необязательным, означает 0 или 1. То же самое, что и {0,1}.</li><li>* — 0 или более, {0,}.</li><li>+ — 1 или более, {1,}.</li><li>{n} — означает число в фигурных скобках.</li><li>{n,m} — не менее n и не более m раз.</li><li>*? — символ ? после квантификатора делает его ленивым, чтобы найти наименьшее количество совпадений.</li></ul><p>Примеры использования квантификаторов в регулярных выражениях</p><p>Обратите внимание, что квантификатор применяется только к символу, который стоит перед ним.</p><p>Также квантификаторов есть три режима:</p><p>По умолчанию квантификатор всегда работает в жадном режиме. Подробнее о квантификаторах в Java вы можете почитать <a href="https://www.geeksforgeeks.org/quantifiers-in-java/">здесь</a>.</p><p>Примеры их использования рассмотрим чуть дальше.</p><h2>Регулярные выражения в Java</h2><p>Поскольку мы говорим о регекспах в Java, то следует учитывать спецификации данного языка программирования.</p><h3>Экранирование символов в регулярных выражениях Java</h3><p>В коде Java нередко можно встретить обратную косую черту \: этот символ означает, что следующий за ним символ является специальным, и что его нужно особым образом интерпретировать. Так, \n означает перенос строки. Посмотрим на примере:</p><p>Результат:</p><p>Поэтому в регулярных выражениях для, например, метасимволов, используется двойная косая черта, чтобы указать компилятору Java, что это элемент регулярки. Пример записи поиска символов пробела:</p><h3>Ключевые классы</h3><p>Java RegExp обеспечиваются пакетом <a href="https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/util/regex/package-summary.html">java.util.regex</a>. Здесь ключевыми являются три класса:</p><ol><li>Matcher — выполняет операцию сопоставления в результате интерпретации шаблона.</li><li>Pattern — предоставляет скомпилированное представление регулярного выражения.</li><li>PatternSyntaxException — предоставляет непроверенное исключение, что указывает на синтаксическую ошибку, допущенную в шаблоне RegEx.</li></ol><p>Также есть интерфейс MatchResult, который представляет результат операции сопоставления.</p><h2>Примеры использования регулярных выражений в Java</h2><h3>e-mail адрес</h3><p>В качестве первого примера мы упомянули регулярку, которая проверяет e-mail адрес на валидность. И вот как эта проверка выглядит в Java-коде:</p><p>Результат:</p><h3>Телефонный номер</h3><p>Регулярное выражение для валидации номера телефона:</p><p>Эта регулярка ориентирована на российские мобильные номера, а также на городские с кодом из трёх цифр. Попробуйте написать код самостоятельно по принципу проверки e-mail адреса.</p><h3>IP адрес</h3><p>А вот класс для определения валидности IP адреса, записанного в десятичном виде:</p><h3>Правильное количество открытых и закрытых скобок в строке</h3><p>На каждую открытую должна приходиться одна закрытая скобка:</p><h3>Извлечение даты</h3><p>Теперь давайте извлечём дату из строки:</p><p>Проверка:</p><p>Результат:</p><p>А вот использование различных режимов квантификаторов, принцип работы которых мы рассмотрели чуть ранее.</p><h3>Жадный режим</h3><p>Результат:</p><p>В заданном шаблоне первый символ – a. Matcher сопоставляет его с каждым символом текста, начиная с нулевой позиции и захватывая всю строку до конца, в чём и проявляется его «жадность». Вот и получается, что заданная стартовая позиция – это 0, а последняя – 2.</p><h3>Сверхжадный режим</h3><p>Результат:</p><p>Принцип, как и в жадном режиме, только поиск заданного символа в обратном направлении не происходит. В приведённой строке всё аналогично: заданная стартовая позиция – это 0, а последняя – 2.</p><h3>Ленивый режим</h3><p>Результат:</p><p>Здесь всё просто: самое короткое совпадение находится на первой, второй и третьей позиции заданной строки.</p><h2>Выводы</h2><p>Общий принцип использования регулярных выражений сохраняется от языка к языку, однако если мы всё-таки говорим о RegEx в конкретном языке программирования, следует учитывать его спецификации. В Java это экранирование символов, использование специальной библиотеки java.util.regex и её классов.</p><p>А какие примеры использования регулярных выражений в Java хотели бы видеть вы? Напишите в комментариях.</p>]]></content:encoded>
    </item>
    <item>
      <title>Путешествие в golang regexp</title>
      <link>https://tproger.ru/articles/puteshestvie-v-golang-regexp</link>
      <comments>https://tproger.ru/articles/puteshestvie-v-golang-regexp?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ирина Мамиконян]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/puteshestvie-v-golang-regexp</guid>
      <description><![CDATA[<p>В этой статье мы рассмотрим инструмент, с помощью которого можно прорываться через мусор в тексте — регулярные выражения в Golang.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/puteshestvie-v-golang-regexp">Путешествие в golang regexp</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 13 Aug 2021 12:21:28 GMT</pubDate>
      <content:encoded><![CDATA[<p>Приветствую всех, принадлежащих к клубу «Тыжпрограммист, почини утюг», а также просто интересующихся IT-миром!</p><p>В этой статье мы рассмотрим инструмент, с помощью которого можно прорываться через мусор в тексте.  А также фильтровать контент и названия файлов, отлавливать запрещённые/разрешенные команды, парсить SQL-запросы и выпендриваться перед коллегами. Это регулярные выражения ?</p><p>Все примеры описаны для языка Golang, однако общие принципы, синтаксис самих регулярных выражений применимы и к других языкам программирования.</p><h2>В начале было слово…</h2><p>И слово это – паника. Давайте сперва запомним, как надёжней начинать работу с регулярными выражениями. Рассмотрим простейший пример:</p><p>Запустив сей код легким мановением руки… получим то, что всей душой ненавидят пишущие на golang люди — панику. Дело в том, что MustCompile паникует вместо возврата ошибки, как это сделано, например, в методе Compile из того же пакета.</p><p>Поэтому MustCompile рекомендуется использовать только в тех случаях, когда:</p><ul><li>вы на 100% уверены, что регулярное выражение валидно;</li><li>вы очень хотите упростить код с инициализацией каких-нибудь глобальных переменных.</li></ul><p>В остальных случаях лучше подойдёт вариант с возвратом ошибки.</p><p>Простой пример проверки соответствия (который можно скопировать и поломать):</p><h2>Общая информация</h2><ul><li>Немного общих сведений о регулярных выражениях в Golang (regexp пакет):</li><li>синтаксис RE2 (библиотека регулярок от Google);</li><li>кодировка UTF-8 и классы символов Unicode;</li><li>время выполнения линейно зависимо от размера ввода;</li><li>обратные ссылки не поддерживаются (не думайте об этом, просто положите на полочку в своих «чертогах разума», чуть позже будет объяснение);</li><li>для регулярных выражений лучше использовать (аккуратно, ведь там своя специфика) необработанные строки (raw strings, строки без интерпретации экранированных литералов).</li></ul><p>А теперь приступим к более подробному разбору темы.</p><h3>Простые совпадения</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok1.jpg" alt="" /></figure><p>Простые совпадения не несут в себе никакого тайного смысла. Что написано – то и ищем.</p><p>В дальнейшем в простых примерах будем использовать функции:</p><ul><li>MatchString (проверяет, есть ли в строке вхождения регулярного выражения);</li><li>FindAllString (ищет все последовательные непересекающиеся повторения в<br />строке).</li></ul><p>Регулярные выражения будут выделяться синим цветом, а комментарии — серым для создания качественных нейронных связей в голове читателя.</p><p>Совпадение не полное, в последнем слове лишняя «t».</p><p>«Banana» полностью совпадает со строкой.</p><p>«сat» встречается в строке.</p><p>Находятся два вхождения.</p><h3>Якори границ</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok2.jpg" alt="" /></figure><p>Якори границ позволяют нам делить текст на отдельные слова, явно задавать привязку к началу или концу строки/текста.</p><p>Ищем текст, начинающийся с «I am here», но есть пробел перед «I» – не подходит.</p><p>Ищем строку, состоящую только из кота — но он в середине.</p><p>Ищем кота отдельным словом — находим.</p><p>Ищем что-то, заканчивающееся котом — находим.</p><h3>Классы символов (воин, маг, лучник)</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok3.jpg" alt="" /></figure><p>Классы — это краткая запись перечисления символов, объединённых по какому-либо признаку. Также можно использовать posix классы ([:digit:], [:space:], etc.), если так удобней.</p><p>Ищем вхождение пяти любых символов.</p><p>Ищем вхождения сочетаний: «ow&lt;цифра&gt;&lt;конец слова&gt;» через два символа слова с начала строки, любой символ, затем две НЕ цифры, затем снова «ow», цифра, конец.</p><p>Ищем начало текста, три любых символа, «@_», два символа слова, «D», конец.</p><p>Ищем начало текста, «GO», один пробельный символ, одну цифру, любой символ, две цифры, конец.</p><h3>Специальные символы и escape</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok4.jpg" alt="" /></figure><p>Что нужно знать про специальные символы:</p><ul><li>список спецсимволов: ^ $ * + ? { } [ ] \ | ( )</li><li>их нужно экранировать с помощью `\`, т.е.  `\+` = просто +</li></ul><p>Ищем «I» в начале текста, перенос, «am», перенос, «here», конец текста.</p><p>Ищем «I» (в виде 16-ричного кода символа), в начале текста, перенос, «am», перенос, «here», конец текста.</p><p>Ищем… не «a+b=c», а одно и более повторение «a», «b=c», ибо «+» не экранирован.</p><p>Ищем «a|b=c», символ «|» экранирован, всё в порядке.</p><h3>Повторение (жабное, не жабное)</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok5.jpg" alt="" /></figure><p>Повторения являются, пожалуй, одной из важнейших фич при работе с регулярными выражениями. Как минимум, из-за того, что дают возможность исключать некоторые подвыражения из обязательных (при использовании?). ЖаБным оно стало в связи со случайной опечаткой и осознанием, что так запоминается лучше.</p><p>Ищем все вхождения чисел из одной и более цифр.</p><p>Ищем начало текста, одно повторение «А», от одного до 3 повторений «G», одно и более повторение «А», от 0 до 2 повторений «!».</p><p>Пытаемся найти все вхождения тегов — из-за жадного повторения получаем весь текст как первое вхождение, ибо весь текст также соответствует выражению &lt;.*&gt; — начинается скобкой, дальше имеет 0 и более любых символов, заканчивается скобкой.</p><p>Пытаемся найти все вхождения тегов, используя не жадное повторение — происходит магия, все срабатывает.</p><h3>Квадратные скобки, ИЛИ и НЕ</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok6.jpg" alt="" /></figure><p>Квадратные скобки эквивалентны перечислению (перечислению с отрицанием при использовании ^). Прямая черта | равнозначна набору альтернативных вариантов из слов. Крышечкой ^ обозначается отрицание при использовании внутри квадратных скобок.</p><p>Ищем либо «good», либо «bad», либо один символ в конце текста, не являющийся пробельным, «i», «c» или «e».</p><p>Ищем начало текста, ноль или более (лучше меньше, не жадное повторение) символов из перечня [a, A , u , U , f ,F], «go» или «python», пробел, от одной до трех цифр, точку, одну цифру и конец текста).</p><p>Ищем начало текста, один и более символов из перечня [h, a, H, A], конец текста.</p><p>Ищем начало текста, один и более символов из перечня [h, a, H, A] либо ноль и более символов из перечня [g, o, G, O], конец текста – пустая строка соответствует второму варианту после прямой черты.</p><h3>Группы</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok7.jpg" alt="" /></figure><p>Важное о группах:</p><ul><li>позволяют поместить часть совпадения в отдельный массив;</li><li>квантификатор после скобок группы применяется ко всей группе (под квантификаторами подразумеваются такие товарищи, как: +, *, {min, max}, etc.);</li><li>группа 0 всегда относится ко всему выражению;</li><li>группа 1 — к подвыражению, начинающемуся с “(“ и заканчивающемуся “)”  (и так далее);</li><li>при повторении группы в качестве «группы 1» берется последнее совпадение.</li></ul><p>В примерах некоторые элементы подчеркнуты. Это не баг, это фича, помогающая увидеть, какой элемент в какой список групп попал. Также используется новая функция — FindAllStringSubmatch — возвращающая срез последовательных непересекающихся подсовпадений (совпадений скобочных групп). Вторым параметром в данной функции является ограничение количества найденных подсовпадений (найдется всё, если использовать -1).</p><p>Тема групп совсем не проста, поэтому пробуйте разное, ломайте, дебажьте.</p><p>Ищем все подсовпадения с выражением «любой символ, одна и более цифра», находим три вхождения, в каждом из которых есть группа 0 – всё вхождение целиком – и группа 1 – часть с «одна и более цифра».</p><p>Выделяем год, месяц и день в отдельные группы, ищем (4 цифры), тире, (2 цифры), тире, (2 цифры).  Получаем одно подсовпадение, где группа 0 — вся дата, группа 1 — год, группа 2 — месяц, группа 3 — день.</p><p>Парсинг дат в разных форматах может быть использован в кейсах, когда нам необходимо, например, сделать предположение о возможном содержимом столбцов с данными из стороннего датафрейма и выделить колонки с. временными метками. Реализация без регулярных выражений будет достаточно неудобна.</p><p>Как ни странно, в группе может быть внутренняя подгруппа (а в ней ещё одна…и ещё…). Здесь мы ищем ноль и более (лучше меньше) любых символов, одно и более повторение символа из перечня [a-zA-Z\-0-9], слэш, любой символ, 2 и более повторения символов из перечня [a-zA-Z]. В итоге находим одно вхождение, где группа 0 – все выражение, группа 1, как внешняя, целиком соответствует части «одно и более повторение символа из перечня [a-zA-Z\-0-9], слэш, любой символ, 2 и более повторения символов из перечня [a-zA-Z]», а группа 2 – части «одно и более повторение символа из перечня [a-zA-Z\-0-9]».</p><p>Вспоминается мем (в нём, кстати, есть мааленькая опечатка :), кто отыщет?):</p><figure><img src="https://media.tproger.ru/uploads/2021/07/ris1.jpg" alt="" /></figure><p>С группами, как и с математическим анализом, нужно сесть, поплакать, хорошо разобраться один раз и работать на автомате в дальнейшем…</p><h3>Именованные и необязательные группы</h3><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok8.jpg" alt="" /></figure><p>Еще один факт о регулярных выражениях в Golang:</p><ul><li>обратных ссылок тут нет (!) (запоминание встретившейся группы для повторного использования в том же выражении).</li></ul><p>Иногда этот факт вызывает головную боль.</p><p>В примерах используется новая вспомогательная функция — SubexpNames — позволяющая получить доступ к списку разделённых по названию групп подсовпадений.</p><p>Пытаемся выловить из мусорного текста дату, разделив её на год, месяц, день. В группу Year попадают первые 4 цифры до тире, группу Month — 2 цифры до следующего тире, Day — последние 2 цифры. Доступ к разделенным по названиям групп подсовпадениям получаем при помощи прохождения по re.SubexpNames()</p><p>Ищем go либо Go (группа, которая не попадает в список подсовпадений благодаря ?: после открывающей скобки группы), py либо Py — находим два подсовпадения, где группа 0 — вхождение целиком, группа 1 – вторая группа<br />(которая «py либо Py»).</p><h3>Другие функции для работы с регулярными выражениями</h3><p>Формула функций работы с регулярными выражениями:</p><figure><img src="https://media.tproger.ru/uploads/2021/07/Snimok9.jpg" alt="" /></figure><p>Также рассмотрим несколько иных функций на примерах.</p><p>Дальше будет сложно. Слабонервным рекомендуется закрыть статью, отойти от экранов и уехать жить в Лондон (почему бы и нет).</p><h3>Большие примеры с кейсами применения регулярных выражений</h3><h4>Валидация логина:</h4><h4>Фильтрация трафика syslog (привет работающим с logstash и его фильтрами):</h4><h4>Парсинг имен таблиц и баз данных, к которым идет обращение, из SELECT SQL-запроса:</h4><h3>Маленькое заключение</h3><p>Регулярные выражения — достаточно полезная штука при анализе текста, парсинге потокаданных, когда необходимо вытащить оттуда нечто действительно важное…ну и вообще для всякого рода магии ?</p><p>Разбирайтесь, не бойтесь экспериментировать и развлекайтесь!</p>]]></content:encoded>
    </item>
    <item>
      <title>Python RegEx: практическое применение регулярок</title>
      <link>https://tproger.ru/translations/regular-expression-python</link>
      <comments>https://tproger.ru/translations/regular-expression-python?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/regular-expression-python</guid>
      <description><![CDATA[<p>Полный гайд по регулярным выражениям в Python: синтаксис re, match, search, findall, sub с примерами. Освойте regex за один урок.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/regular-expression-python">Python RegEx: практическое применение регулярок</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 19 Jan 2021 11:20:32 GMT</pubDate>
      <content:encoded><![CDATA[<p>Рассмотрим регулярные выражения в Python, начиная синтаксисом и заканчивая примерами использования.</p><p>• Регулярные выражения в Python работают через модуль re — достаточно одного import re для начала работы
• re.match() ищет совпадение только в начале строки, re.search() — по всей строке, re.findall() — возвращает все совпадения
• Метасимволы \d, \w, \s и квантификаторы *, +, ? позволяют описать практически любой текстовый шаблон
• re.compile() экономит ресурсы при многократном использовании одного и того же шаблона
• Группировка через круглые скобки () позволяет извлекать конкретные части совпадения — например, домен из email или год из даты</p><p>Примечание Вы читаете улучшенную версию некогда выпущенной нами статьи.</p><ol><li><a href="https://tproger.ru/#part0">Основы регулярных выражений</a></li><li><a href="https://tproger.ru/#part2">Регулярные выражения в Python</a></li><li><a href="https://tproger.ru/#part3">Задачи</a></li></ol><h2>Основы регулярных выражений</h2><p>Регулярками в Python называются шаблоны, которые используются для поиска соответствующего фрагмента текста и сопоставления символов.</p><p>Грубо говоря, у нас есть input-поле, в которое должен вводиться email-адрес. Но пока мы не зададим проверку валидности введённого email-адреса, в этой строке может оказаться совершенно любой набор символов, а нам это не нужно.</p><p>Чтобы выявить ошибку при вводе некорректного адреса электронной почты, можно использовать следующее регулярное выражение:</p><p>По сути, наш шаблон — это набор символов, который проверяет строку на соответствие заданному правилу. Давайте разберёмся, как это работает.</p><h3>Синтаксис RegEx</h3><p>Синтаксис у регулярок необычный. Символы могут быть как буквами или цифрами, так и метасимволами, которые задают шаблон строки:</p><figure><img src="https://media.tproger.ru/uploads/2021/01/3-9.jpg" alt="" /></figure><p>Также есть дополнительные конструкции, которые позволяют сокращать регулярные выражения:</p><ul><li>\d — соответствует любой одной цифре и заменяет собой выражение [0-9];</li><li>\D — исключает все цифры и заменяет [^0-9];</li><li>\w — заменяет любую цифру, букву, а также знак нижнего подчёркивания;</li><li>\W — любой символ кроме латиницы, цифр или нижнего подчёркивания;</li><li>\s — соответствует любому пробельному символу;</li><li>\S — описывает любой непробельный символ.</li></ul><h3>Для чего используются регулярные выражения</h3><ul><li>для определения нужного формата, например телефонного номера или email-адреса;</li><li>для разбивки строк на подстроки;</li><li>для поиска, замены и извлечения символов;</li><li>для быстрого выполнения нетривиальных операций.</li></ul><p>Синтаксис  таких выражений в основном стандартизирован, так что вам следует понять их лишь раз, чтобы использовать в любом языке программирования.</p><p>Примечание Не стоит забывать, что регулярные выражения не всегда оптимальны, и для простых операций часто достаточно встроенных в Python функций.</p><p>Хотите узнать больше? Обратите внимание на статью о <a href="https://tproger.ru/articles/regexp-for-beginners/">регулярках для новичков</a>.</p><h2>Регулярные выражения в Python</h2><p>В Python для работы с регулярками есть модуль re. Его нужно просто импортировать:</p><p>А вот наиболее популярные методы, которые предоставляет модуль:</p><ul><li>re.match()</li><li>re.search()</li><li>re.findall()</li><li>re.split()</li><li>re.sub()</li><li>re.compile()</li></ul><p>Рассмотрим каждый из них подробнее.</p><h3>re.match(pattern, string)</h3><p>Этот метод ищет по заданному шаблону в начале строки. Например, если мы вызовем метод match() на строке «AV Analytics AV» с шаблоном «AV», то он завершится успешно. Но если мы будем искать «Analytics», то результат будет отрицательный:</p><p>Искомая подстрока найдена. Чтобы вывести её содержимое, применим метод group() (мы используем «r» перед строкой шаблона, чтобы показать, что это «сырая» строка в Python):</p><p>Теперь попробуем найти «Analytics» в данной строке. Поскольку строка начинается на «AV», метод вернет None:</p><p>Также есть методы start() и end() для того, чтобы узнать начальную и конечную позицию найденной строки.</p><p>Эти методы иногда очень полезны для работы со строками.</p><h3>re.search(pattern, string)</h3><p>Метод похож на match(), но ищет не только в начале строки. В отличие от предыдущего, search() вернёт объект, если мы попытаемся найти «Analytics»:</p><p>Метод search() ищет по всей строке, но возвращает только первое найденное совпадение.</p><h3>re.findall(pattern, string)</h3><p>Возвращает список всех найденных совпадений. У метода findall() нет ограничений на поиск в начале или конце строки. Если мы будем искать «AV» в нашей строке, он вернет все вхождения «AV». Для поиска рекомендуется использовать именно findall(), так как он может работать и как re.search(), и как re.match().</p><h3>re.split(pattern, string, [maxsplit=0])</h3><p>Этот метод разделяет строку по заданному шаблону.</p><p>В примере мы разделили слово «Analytics» по букве «y». Метод split() принимает также аргумент maxsplit со значением по умолчанию, равным 0. В данном случае он разделит строку столько раз, сколько возможно, но если указать этот аргумент, то разделение будет произведено не более указанного количества раз. Давайте посмотрим на примеры Python RegEx:</p><p>Мы установили параметр maxsplit равным 1, и в результате строка была разделена на две части вместо трех.</p><h3>re.sub(pattern, repl, string)</h3><p>Ищет шаблон в строке и заменяет его на указанную подстроку. Если шаблон не найден, строка остается неизменной.</p><h3>re.compile(pattern, repl, string)</h3><p>Мы можем собрать регулярное выражение в отдельный объект, который может быть использован для поиска. Это также избавляет от переписывания одного и того же выражения.</p><p>До сих пор мы рассматривали поиск определенной последовательности символов. Но что, если у нас нет определенного шаблона, и нам надо вернуть набор символов из строки, отвечающий определенным правилам? Такая задача часто стоит при извлечении информации из строк. Это можно сделать, написав выражение с использованием специальных символов. Вот наиболее часто используемые из них:</p><figure><img src="https://media.tproger.ru/user-uploads/33794/2023-12-20/b7899beb-e245-46fd-9f94-e1721cb810be.png" alt="" /></figure><p>Больше информации по специальным символам можно найти в <a href="https://docs.python.org/3.8/library/re.html">документации</a> для регулярных выражений в Python 3.</p><p>Перейдём к практическому применению Python регулярных выражений и рассмотрим примеры.</p><h2>Задачи</h2><h3>Вернуть первое слово из строки</h3><p>Сначала попробуем вытащить каждый символ (используя .)</p><p>Для того, чтобы в конечный результат не попал пробел, используем вместо . \w.</p><p>Теперь попробуем достать каждое слово (используя * или +)</p><p>И снова в результат попали пробелы, так как * означает «ноль или более символов». Для того, чтобы их убрать, используем +:</p><p>Теперь вытащим первое слово, используя ^:</p><p>Если мы используем $ вместо ^, то мы получим последнее слово, а не первое:</p><h3>Вернуть первые два символа каждого слова</h3><p>Вариант 1: используя \w, вытащить два последовательных символа, кроме пробельных, из каждого слова:</p><p>Вариант 2: вытащить два последовательных символа, используя символ границы слова (\b):</p><h3>Вернуть домены из списка email-адресов</h3><p>Сначала вернём все символы после «@»:</p><p>Как видим, части «.com», «.in» и т. д. не попали в результат. Изменим наш код:</p><p>Второй вариант — вытащить только домен верхнего уровня, используя группировку — ( ):</p><h3>Извлечь дату из строки</h3><p>Используем \d для извлечения цифр.</p><p>Для извлечения только года нам опять помогут скобки:</p><h3>Извлечь слова, начинающиеся на гласную</h3><p>Для начала вернем все слова:</p><p>А теперь — только те, которые начинаются на определенные буквы (используя []):</p><p>Выше мы видим обрезанные слова «argest» и «ommunity». Для того, чтобы убрать их, используем \b для обозначения границы слова:</p><p>Также мы можем использовать ^ внутри квадратных скобок для инвертирования группы:</p><p>В результат попали слова, «начинающиеся» с пробела. Уберем их, включив пробел в диапазон в квадратных скобках:</p><h3>Проверить формат телефонного номера</h3><p>Номер должен быть длиной 10 знаков и начинаться с 8 или 9. Есть список телефонных номеров, и нужно проверить их, используя регулярки в Python:</p><h3>Разбить строку по нескольким разделителям</h3><p>Возможное решение:</p><p>Также мы можем использовать метод re.sub() для замены всех разделителей пробелами:</p><h3>Извлечь информацию из html-файла</h3><p>Допустим, нужно извлечь информацию из html-файла, заключенную между &lt;td&gt; и &lt;/td&gt;, кроме первого столбца с номером. Также будем считать, что html-код содержится в строке.</p><p>Пример содержимого html-файла:</p><p>С помощью регулярных выражений в Python это можно решить так (если поместить содержимое файла в переменную test_str):</p><h2>Часто задаваемые вопросы</h2><h3>Что такое регулярные выражения в Python?</h3><p>Регулярные выражения (Regular Expressions, RegEx) — это специальный язык шаблонов для поиска, сопоставления и замены текста. В Python для работы с ними используется встроенный модуль re, который предоставляет функции match, search, findall, sub и другие. Регулярки применяются для валидации данных, парсинга логов, извлечения информации из строк и многих других задач обработки текста.</p><h3>Чем отличается re.match() от re.search()?</h3><p>re.match() ищет совпадение с шаблоном только в начале строки. Если шаблон не найден в самом начале — возвращается None, даже если совпадение есть дальше. re.search() просматривает всю строку и возвращает первое найденное совпадение в любой позиции. Для поиска всех вхождений используйте re.findall().</p><h3>Как проверить email с помощью регулярного выражения?</h3><p>Базовый шаблон для проверки email выглядит так: r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)+$'. Он проверяет наличие символов до @, доменного имени и хотя бы одной точки с доменной зоной после неё. Для продакшен-валидации рекомендуется дополнительно проверять длину и использовать специализированные библиотеки, так как полная спецификация email-адресов значительно сложнее.</p><h3>Какие самые полезные спецсимволы в регулярках?</h3><p>Наиболее используемые спецсимволы: \d (любая цифра), \w (буква, цифра или подчёркивание), \s (пробельный символ), . (любой символ кроме переноса строки). Квантификаторы + (один или более), * (ноль или более) и ? (ноль или один) управляют количеством повторений. Символы ^ и $ обозначают начало и конец строки, а квадратные скобки [] задают набор допустимых символов.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 шпаргалок по Python для разных сфер применения</title>
      <link>https://tproger.ru/articles/python-cheatsheets</link>
      <comments>https://tproger.ru/articles/python-cheatsheets?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Марина Александровна]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/python-cheatsheets</guid>
      <description><![CDATA[<p>Подборка шпаргалок по основам языка, регулярным выражениям и библиотеке pandas для анализа данных — базовую информацию не придётся искать.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/python-cheatsheets">5 шпаргалок по Python для разных сфер применения</a>»</p>]]></description>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Шпаргалки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 05 Nov 2020 13:02:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Держите несколько шпаргалок по Python, которые сэкономят вам время в процессе обучения и работы с популярным языком программирования.</p><ol><li><a href="https://tproger.ru/#part1">Шпаргалка по основам Python</a></li><li><a href="https://tproger.ru/#part2">Регулярные выражения в Python</a></li><li><a href="https://tproger.ru/#part3">Шпаргалка по pandas</a></li><li><a href="https://tproger.ru/#part4">Шпаргалка по Django</a></li><li><a href="https://tproger.ru/#part5">Виртуальное окружение Python</a></li></ol><h2>Шпаргалка по основам Python</h2><p>Здесь собраны переменные, методы, индексы и срезы, а также форматирование дат с соответствующими подсказками в сносках. Если вы только начали изучать программирование на языке Python, смело обращайтесь к этой шпаргалке:</p><figure><img src="https://media.tproger.ru/uploads/2020/11/python_basics_cheat_sheet.jpg" alt="" /></figure><h2>Регулярные выражения в Python</h2><p>Шпаргалка собрала большое количество информации о регулярках, включая:</p><ul><li>специальные символы;</li><li>объекты Match;</li><li>методы модуля re;</li><li>escape-символы;</li><li>Raw String Notation;</li><li>расширения;</li><li>объекты;</li><li>флаги;</li><li>ссылки на документацию: <a href="https://docs.python.org/3/howto/regex.html">Regular Expression HOWTO</a> и <a href="https://docs.python.org/3/library/re.html">Regular expression operations</a>.</li></ul><figure><img src="https://media.tproger.ru/uploads/2020/11/python_regex_cheat_sheet.jpg" alt="" /></figure><h2>Шпаргалка по pandas</h2><p>Эта библиотека для анализа данных прекрасно себя зарекомендовала в Data Science. Такая шпаргалка поможет в построении различных диаграмм с использованием pandas:</p><figure><img src="https://media.tproger.ru/uploads/2020/11/pandas_plotting_cheat_sheet.jpg" alt="" /></figure><h2>Шпаргалка по Django</h2><p>Будет полезна тем, кто желает освоить веб-разработку на Python. Здесь вы найдёте базовую информацию по работе с фреймворком — от его установки и до операций с Git:</p><figure><img src="https://media.tproger.ru/uploads/2020/11/django_cheatsheet.png" alt="" /></figure><h2>Виртуальное окружение Python</h2><p>Эта шпаргалка собрала популярные инструменты для создания и работы с изолированными средами, а также команды по установке данных инструментов и активации виртуального окружения:</p><figure><img src="https://media.tproger.ru/uploads/2020/11/puthon_virtual_environments__cheat_sheet.jpg" alt="" /></figure>]]></content:encoded>
    </item>
    <item>
      <title>Регулярные выражения: начало работы с RegExp</title>
      <link>https://tproger.ru/articles/regexp-for-beginners</link>
      <comments>https://tproger.ru/articles/regexp-for-beginners?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/regexp-for-beginners</guid>
      <description><![CDATA[<p>Разбираем синтаксис регулярных выражений с нуля: символьные классы, квантификаторы, группы и примеры. Начните писать RegExp уже сегодня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/regexp-for-beginners">Регулярные выражения: начало работы с RegExp</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 28 Jan 2017 15:49:23 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Что такое регулярные выражения?</h2><p>• Регулярные выражения (RegExp) — язык шаблонов для поиска, валидации и замены текста
• Базовые элементы: символьные классы (\d, \w, \s), наборы [abc], диапазоны [a-z] и квантификаторы (+, *, ?, {n,m})
• Скобочные группы позволяют запоминать совпадения и ссылаться на них через \1, \2
• Три режима квантификации: жадный (по умолчанию), ленивый (*?) и ревнивый (*+)</p><p>Давайте разберёмся, что же собой представляют регулярные выражения. Если вам когда-нибудь приходилось работать с командной строкой, вы, вероятно, использовали маски имён файлов. Например, чтобы удалить все файлы в текущей директории, которые начинаются с буквы "d", можно написать rm d*.</p><p>Регулярные выражения представляют собой похожий, но гораздо более сильный инструмент для поиска строк, проверки их на соответствие какому-либо шаблону и другой подобной работы. Англоязычное название этого инструмента — Regular Expressions или просто RegExp. Строго говоря, регулярные выражения — специальный язык для описания шаблонов строк.</p><p>Реализация этого инструмента различается в разных языках программирования, хоть и не сильно. В данной статье мы будем ориентироваться в первую очередь на реализацию Perl Compatible Regular Expressions.</p><h2>Основы синтаксиса</h2><p>В первую очередь стоит заметить, что любая строка сама по себе является регулярным выражением. Так, выражению Хаха, очевидно, будет соответствовать строка "Хаха" и только она. Регулярки являются регистрозависимыми, поэтому строка "хаха" (с маленькой буквы) уже не будет соответствовать выражению выше.</p><p>Однако уже здесь следует быть аккуратным — как и любой язык, регекспы имеют спецсимволы, которые нужно экранировать. Вот их список:  . ^ $ * + ? { } [ ] \\ | ( ). Экранирование осуществляется обычным способом — добавлением \\ перед спецсимволом.</p><h2>Набор символов</h2><p>Предположим, мы хотим найти в тексте все междометия, обозначающие смех. Просто Хаха нам не подойдёт — ведь под него не попадут "Хехе", "Хохо" и "Хихи". Да и проблему с регистром первой буквы нужно как-то решить.</p><p>Здесь нам на помощь придут наборы — вместо указания конкретного символа, мы можем записать целый список, и если в исследуемой строке на указанном месте будет стоять любой из перечисленных символов, строка будет считаться подходящей. Наборы записываются в квадратных скобках — паттерну [abcd] будет соответствовать любой из символов "a", "b", "c" или "d".</p><p>Внутри набора б<b>о</b>льшая часть спецсимволов не нуждается в экранировании, однако использование \\ перед ними не будет считаться ошибкой. По прежнему необходимо экранировать символы "\\" и "^", и, желательно, "]" (так, [][] обозначает любой из символов "]" или «[», тогда как [[]х] — исключительно последовательность "[х]"). Необычное на первый взгляд поведение регулярок с символом "]" на самом деле определяется известными правилами, но гораздо легче просто экранировать этот символ, чем их запоминать. Кроме этого, экранировать нужно символ «-», он используется для задания диапазонов (см. ниже).</p><p>Если сразу после [ записать символ ^, то набор приобретёт обратный смысл — подходящим будет считаться любой символ кроме указанных. Так, паттерну [^xyz] соответствует любой символ, кроме, собственно, "x", "y" или "z".</p><p>Итак, применяя данный инструмент к нашему случаю, если мы напишем [Хх][аоие]х[аоие], то каждая из строк "Хаха", "хехе", "хихи" и даже "Хохо" будут соответствовать шаблону.</p><h3>Предопределённые классы символов</h3><p>Для некоторых наборов, которые используются достаточно часто, существуют специальные шаблоны. Так, для описания любого пробельного символа (пробел, табуляция, перенос строки) используется \\s, для цифр — \\d, для символов латиницы, цифр и подчёркивания "_" — \\w.</p><p>Если необходимо описать вообще любой символ, для этого используется точка — .. Если указанные классы написать с заглавной буквы (\\S, \\D, \\W) то они поменяют свой смысл на противоположный — любой непробельный символ, любой символ, который не является цифрой, и любой символ кроме латиницы, цифр или подчёркивания соответственно.</p><p>Также с помощью регулярных выражений есть возможность проверить положение строки относительно остального текста. Выражение \\b обозначает границу слова, \\B — не границу слова, ^ — начало текста, а $ — конец. Так, по паттерну \\bJava\\b в строке "Java and JavaScript" найдутся первые 4 символа, а по паттерну \\bJava\\B — символы c 10-го по 13-й (в составе слова "JavaScript").</p><figure><img src="https://media.tproger.ru/uploads/2017/01/iknowregularexpressions.jpg" alt="" /></figure><h3>Диапазоны</h3><p>У вас может возникнуть необходимость обозначить набор, в который входят буквы, например, от "б" до "ф". Вместо того, чтобы писать [бвгдежзиклмнопрстуф] можно воспользоваться механизмом диапазонов и написать [б-ф]. Так, паттерну x[0-8A-F][0-8A-F] соответствует строка "xA6", но не соответствует "xb9" (во-первых, из-за того, что в диапазоне указаны только заглавные буквы, во-вторых, из-за того, что 9 не входит в промежуток 0-8).</p><p>Механизм диапазонов особенно актуален для русского языка, ведь для него нет конструкции, аналогичной \\w. Чтобы обозначить все буквы русского алфавита, можно использовать паттерн [а-яА-ЯёЁ]. Обратите внимание, что буква "ё" не включается в общий диапазон букв, и её нужно указывать отдельно.</p><h2>Квантификаторы</h2><p>Вернёмся к нашему примеру. Что, если в "смеющемся" междометии будет больше одной гласной между буквами "х", например "Хаахаааа"? Наша старая регулярка уже не сможет нам помочь. Здесь нам придётся воспользоваться квантификаторами.</p><figure><img src="https://media.tproger.ru/uploads/2017/01/table1.png" alt="" /></figure><p>Обратите внимание, что квантификатор применяется только к символу, который стоит перед ним.</p><p>Некоторые часто используемые конструкции получили в языке RegEx специальные обозначения:</p><figure><img src="https://media.tproger.ru/uploads/2017/01/table2.png" alt="" /></figure><p>Таким образом, с помощью квантификаторов мы можем улучшить наш шаблон для междометий до [Хх][аоеи]+х[аоеи]*, и он сможет распознавать строки "Хааха", "хееееех" и "Хихии".</p><h3>Ленивая квантификация</h3><p>Предположим, перед нами стоит задача — найти все HTML-теги в строке</p><p>Очевидное решение &lt;.*&gt; здесь не сработает — оно найдёт всю строку целиком, т.к. она начинается с тега абзаца и им же заканчивается. То есть содержимым тега будет считаться строка</p><p>Это происходит из-за того, что по умолчанию квантификатор работают по т.н. жадному алгоритму — старается вернуть как можно более длинную строку, соответствующую условию. Решить проблему можно двумя способами. Первый — использовать выражение &lt;[^&gt;]*&gt;, которое запретит считать содержимым тега правую угловую скобку. Второй — объявить квантификатор не жадным, а ленивым. Делается это с помощью добавления справа к квантификатору символа ?. Т.е. для поиска всех тегов выражение обратится в &lt;.*?&gt;.</p><h3>Ревнивая квантификация</h3><p>Иногда для увеличения скорости поиска (особенно в тех случаях, когда строка не соответствует регулярному выражению) можно использовать запрет алгоритму возвращаться к предыдущим шагам поиска для того, чтобы найти возможные соответствия для оставшейся части RegExp. Это называется ревнивой квантификацией. Квантификатор делается ревнивым с помощью добавления к нему справа символа +. Ещё одно применение ревнивой квантификации — исключение нежелательных совпадений. Так, паттерну ab*+a в строке "ababa" будут соответствовать только первые три символа, но не символы с третьего по пятый, т.к. символ "a", который стоит на третьей позиции, уже был использован для первого результата.</p><p>Чуть больше о жадном, сверхжадном и ленивом режимах квантификации вы сможете узнать из статьи о <a href="https://tproger.ru/articles/java-regex-ispolzovanie-reguljarnyh-vyrazhenij-na-praktike/">регулярных выражениях в Java</a>.</p><h2>Скобочные группы</h2><p>Для нашего шаблона "смеющегося" междометия осталась самая малость — учесть, что буква "х" может встречаться более одного раза, например "Хахахахааахахооо", а может и вовсе заканчиваться на букве "х". Вероятно, здесь нужно применить квантификатор для группы [аиое]+х, но если мы просто напишем [аиое]х+, то квантификатор + будет относиться только к символу "х", а не ко всему выражению. Чтобы это исправить, выражение нужно взять в круглые скобки: ([аиое]х)+.</p><p>Таким образом, наше выражение превращается в [Хх]([аиое]х?)+ — сначала идёт заглавная или строчная "х", а потом произвольное ненулевое количество гласных, которые (возможно, но не обязательно) перемежаются одиночными строчными "х". Однако это выражение решает проблему лишь частично — под это выражение попадут и такие строки, как, например, "хихахех" — кто-то может быть так и смеётся, но допущение весьма сомнительное. Очевидно, мы можем использовать набор из всех гласных лишь единожды, а потом должны как-то опираться на результат первого поиска. Но как?…</p><h3>Запоминание результата поиска по группе</h3><p>Оказывается, результат поиска по скобочной группе записывается в отдельную ячейку памяти, доступ к которой доступен для использования в последующих частях регэкспа. Возвращаясь к задаче с поиском HTML-тегов на странице, нам может понадобиться не только найти теги, но и узнать их название. В этом нам может помочь регулярное выражение &lt;(.*?)&gt;.</p><p>Результат поиска по всему регексу: "", "<b>", "</b>", "<i>", "</i>", "".<br />Результат поиска по первой группе: "p", "b", "/b", "i", "/i", "/i", "/p".</p><p>На результат поиска по группе можно ссылаться с помощью выражения \\n, где n — цифра от 1 до 9. Например выражению (\\w)(\\w)\\1\\2 соответствуют строки "aaaa", "abab", но не соответствует "aabb".</p><p>Если выражение берётся в скобки только для применения к ней квантификатора (не планируется запоминать результат поиска по этой группе), то сразу после первой скобки стоит добавить ?:, например (?:[abcd]+\\w).</p><p>С использованием этого механизма мы можем переписать наше выражение к виду [Хх]([аоие])х?(?:\\1х?)*.</p><figure><img src="https://media.tproger.ru/uploads/2017/01/RegEx-lovehate.jpg" alt="" /></figure><h3>Перечисление</h3><p>Чтобы проверить, удовлетворяет ли строка хотя бы одному из шаблонов, можно воспользоваться аналогом булевого оператора OR, который записывается с помощью символа |. Так, под шаблон Анна|Одиночество попадают строки "Анна" и "Одиночество" соответственно. Особенно удобно использовать перечисления внутри скобочных групп. Так, например (?:a|b|c|d) полностью эквивалентно [abcd] (в данном случае второй вариант предпочтительнее в силу производительности и читаемости).</p><p>С помощью этого оператора мы сможем добавить к нашему регулярному выражению для поиска междометий возможность распознавать смех вида "Ахахаах" — единственной усмешке, которая начинается с гласной: [Хх]([аоие])х?(?:\\1х?)*|[Аа]х?(?:ах?)+</p><h2>Полезные сервисы</h2><p>Потренироваться и/или проверить регулярное выражение на каком-либо тексте без написания кода можно с помощью таких сервисов, как <a href="http://regexr.com/">RegExr</a>, <a href="http://regexpal.com/">Regexpal</a> или <a href="https://regex101.com/">Regex101</a>. Последний вдобавок приводит краткие пояснения к тому, как работает регулярка.</p><p>Разобраться, как работает регулярное выражение, которое попало к вам в руки, можно с помощью сервиса <a href="https://regexper.com/">Regexper</a> — он умеет строить понятные диаграмы по регуляркам.</p><p><a href="http://regexpres.narod.ru/calculator.html">RegExp Builder</a> — визуальный конструктор функций JavaScript для работы с регулярными выражениями.</p><p>Больше инструментов можно найти в нашей <a href="https://tproger.ru/digest/best-regex-testers/">подборке</a>.</p><h2>Задания для закрепления</h2><h3>Найдите время</h3><p>Время имеет формат часы:минуты. И часы, и минуты состоят из двух цифр, пример: 09:00. Напишите RegEx выражение для поиска времени в строке: "Завтрак в 09:00". Учтите, что "37:98" — некорректное время.</p><h3>Java[^script]</h3><p>Найдет ли регулярка Java[^script] что-нибудь в строке Java? А в строке JavaScript?</p><h3>Цвет</h3><p>Напишите регулярное выражение для поиска HTML-цвета, заданного как #ABCDEF, то есть # и содержит затем 6 шестнадцатеричных символов.</p><h3>Разобрать арифметическое выражение</h3><p>Арифметическое выражение состоит из двух чисел и операции между ними, например:</p><ul><li>1 + 2</li><li>1.2 *3.4</li><li>-3/ -6</li><li>-2-2</li></ul><p>Список операций: "+", «-», "*" и "/".</p><p>Также могут присутствовать пробелы вокруг оператора и чисел.</p><p>Напишите регулярку, которая найдёт, как всё арифметическое действие, так и (через группы) два операнда.</p><h3>Кроссворды из регулярных выражений</h3><p>Такие <a href="https://tproger.ru/digest/regex-crosswords/">кроссворды</a> вы можете найти у нас.</p><h2>Часто задаваемые вопросы</h2><h3>Чем регулярные выражения отличаются от обычного поиска по строке?</h3><p>Обычный поиск ищет точное совпадение подстроки, тогда как регулярные выражения позволяют описывать шаблоны с переменными частями. Например, RegExp может найти все email-адреса в тексте, все даты определённого формата или все слова, начинающиеся с заглавной буквы — то, что невозможно сделать простым поиском по подстроке.</p><h3>Какие языки программирования поддерживают RegExp?</h3><p>Практически все современные языки: Python (модуль re), JavaScript (встроенный объект RegExp), Java (пакет java.util.regex), C# (System.Text.RegularExpressions), PHP (функции preg_*), Go, Ruby, Rust и другие. Синтаксис в большинстве языков основан на стандарте PCRE (Perl Compatible Regular Expressions).</p><h3>Как проверить регулярное выражение без написания кода?</h3><p>Используйте онлайн-сервисы: Regex101 подсвечивает совпадения и объясняет каждую часть выражения, RegExr предоставляет интерактивный редактор с подсказками, а Regexper строит наглядные диаграммы. Все инструменты работают прямо в браузере и не требуют установки.</p><h3>Когда не стоит использовать регулярные выражения?</h3><p>RegExp не подходят для парсинга вложенных структур (HTML, XML, JSON) — для этого лучше использовать специализированные парсеры. Также не стоит применять регулярки для валидации email по полному стандарту RFC 5322. Если задача решается простым поиском подстроки или методами split/replace — регулярные выражения будут избыточны.</p><p>Удачи и помните — не всегда задачу стоит решать именно с помощью регекспов ("У программиста была проблема, которую он начал решать регэкспами. Теперь у него две проблемы"). <a href="https://tproger.ru/translations/validating-email-right">Иногда лучше</a>, например, написать развёрнутый автомат конечных состояний.</p>]]></content:encoded>
    </item>
    <item>
      <title>Подборка кроссвордов из регулярных выражений</title>
      <link>https://tproger.ru/digest/regex-crosswords</link>
      <comments>https://tproger.ru/digest/regex-crosswords?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван Бирюков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/digest/regex-crosswords</guid>
      <description><![CDATA[<p>Кроссворды из регулярных выражений помогут отвлечься от программирования: головоломка с MIT Puzzle Hunt 2013 года и сайт Regex Crossword.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/digest/regex-crosswords">Подборка кроссвордов из регулярных выражений</a>»</p>]]></description>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Игры для программистов]]></category>
      <category><![CDATA[Подборки]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 08 Oct 2016 15:16:16 GMT</pubDate>
      <content:encoded><![CDATA[<p>Порой хочется как-то отвлечься от программирования. Сделать это и при этом провести время с пользой помогут кроссворды из регулярных выражений — отличное развлечение! Мы собрали для вас подборку таких кроссвордов.</p><figure><img src="https://media.tproger.ru/uploads/2016/10/1-2.png" alt="" /></figure><p>Этот кроссворд был представлен на мероприятии MIT Puzzle Hunt, прошедшем в 2013 году. Для его решения в сети можно найти как минимум две странички с удобным интерфейсом (<a href="http://rampion.github.io/RegHex/">от Rampion</a> и <a href="http://jimbly.github.io/regex-crossword/">от Jimbly</a>).</p><figure><img src="https://media.tproger.ru/uploads/2016/10/3-1.png" alt="" /></figure><p>Ещё один <a href="http://mariolurig.com/crossword/">кроссворд</a>, на этот раз в более привычном формате.</p><figure><img src="https://media.tproger.ru/uploads/2016/10/4-1.png" alt="" /></figure><p><a href="https://regexcrossword.com">Regex Crossword</a> — сайт, где представлены целых 10 кроссвордов, которые можно решать, соревнуясь с другими пользователями. Чем еще удобен сайт, так это инструкцией по решению таких задачек.</p><p>Если вас заинтересовали регулярные выражения и эти интересные задачки, то вот ещё два ресурса, которые могут вам пригодиться:</p><ul><li><a href="https://gitlab.com/nikolaterziev2/regex-crosswords">Программа</a> на Python для генерации и решения regex-кроссвордов;</li><li><a href="https://github.com/aloisdg/awesome-regex">Сборник</a> различных материалов (от документации и библиотек до статей и книг) для изучения регулярных выражений.</li></ul><p>Если же вы нашли ещё какой-то кроссворд или другую задачку, связанную с “регулярками”, делитесь ими в комментариях, и мы добавим их в этот пост!</p>]]></content:encoded>
    </item>
    <item>
      <title>Как проверять email адрес на валидность правильно</title>
      <link>https://tproger.ru/translations/validating-email-right</link>
      <comments>https://tproger.ru/translations/validating-email-right?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Пётр Соковых]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/validating-email-right</guid>
      <description><![CDATA[<p>Интуитивное представление о виде почтового адреса подводит: полагаться стоит на спецификацию, а у проверки регулярным выражением есть свои проблемы.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/validating-email-right">Как проверять email адрес на валидность правильно</a>»</p>]]></description>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 17 Aug 2016 18:44:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Предположим, у вас есть простая задача — создать форму, которая даст пользователю возможность подписаться на e-mail оповещения. Разумеется, вам необходимо предотвратить ввод в эту форму всякого мусора, при этом не должно получаться так, чтобы валидный адрес вдруг был забракован системой.</p><p>Как же выглядит e-mail адрес? Интуитивно можно предположить, что так:</p><p>Выглядит хорошо, но это совершенно не тот случай, когда стоит доверять интуиции. Доверять следует <a href="https://tools.ietf.org/html/rfc5322">спецификации</a>. А спецификация говорит нам следующее:</p><p>Конечно, и тут можно обойтись с помощью регулярного выражения:</p><p>Но с этим есть несколько проблем:</p><ul><li>Как вы будете проверять правильность этого монстра? Такие регулярные выражения переходят «из уст в уста» на форумах, и каждый добавляет в них функциональность до тех пор, пока работа с выражением становится невозможной. И это именно тот случай.</li><li>Я бы не сказал, что регулярные выражения такой длины эффективнее, чем другие методы. Чем длиннее выражение, тем дольше оно будет компилироваться (сравнение всегда происходит за O(n)).</li><li>С помощью регулярного выражения можно сделать только проверку на соответствие. Выполнить проверку на то, находится ли домен в чёрном списке, у вас уже, увы, не получится.</li></ul><h3>Давайте пойдём другим путём</h3><p>Вот основа нашей проверки:</p><p>А вот диаграмма, описывающая алгоритм, по которому наша программа будет работать:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/emailaddrfsm.png" alt="" /></figure><p>Если вы заметили, что тут не все правила соблюдаются — не волнуйтесь, мы вернёмся к этому позже. Если вы не заметили, и вообще не понимаете, что тут происходит, то сейчас объясню.</p><p>Вершина графа — состояние проверки. Ребро графа — прочитанный символ. Если в результате считывания символа невозможно перейти ни по одному ребру, значит, адрес не валиден. Вот, например, как будет реализована первая часть этого алгоритма:</p><figure><img src="https://media.tproger.ru/uploads/2016/08/simplecountingfsm.png" alt="" /></figure><p>Теперь о проверках, которые мы сделаем, после того, как код пройдёт по этой диаграмме:</p><h3>Собираем всё вместе</h3>]]></content:encoded>
    </item>
    <item>
      <title>Stack Overflow оказался недоступен из-за работы регулярного выражения</title>
      <link>https://tproger.ru/news/so-regex-fail</link>
      <comments>https://tproger.ru/news/so-regex-fail?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Антон]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/so-regex-fail</guid>
      <description><![CDATA[<p>Причиной недоступности Stack Overflow стала нагрузка на серверы от обработки одного вопроса: регулярное выражение обрезало пробелы по краям строки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/so-regex-fail">Stack Overflow оказался недоступен из-за работы регулярного выражения</a>»</p>]]></description>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 21 Jul 2016 10:13:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Сегодня на Stack Status появился <a href="http://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016">пост</a>, в котором сотрудник сети Stack Exchange, к которой относится сервис Stack Overflow, рассказал о том, почему вчера в течение часа ресурс был недоступен.</p><p>Причиной нестабильности сервиса стала повышенная нагрузка на сервера, связанная с обработкой одного из опубликованных вопросов. Дело в том, что публикуемые на Stack Overflow вопросы перед отображением на странице анализируются набором регулярных выражений, в числе которых следующее: ^[\s\u200c]+|[\s\u200c]+$ — оно служит для обрезания пробелов (в том числе в Unicode) с концов строки. И камнем преткновения стал пост, который содержал в середине текста последовательность из 20 000 (!) пробелов.</p><p>Вышеупомянутое регулярное выражение обрабатывало такую строку следующим образом: найдя первый пробел, оно переходил к следующему, затем к следующему и т.д. до самого последнего пробела в последовательности. После ожидался конец строки, однако строка из пробелов оказалась в середине поста, поэтому движок конец строки там, естественно, не обнаруживал. Тогда предпринималась попытка найти соответствие в следующей возможной последовательности символов, и движок принимался анализировать ту же строку, начиная со второго пробела, затем переходя к третьему, затем — к четвертому и т.д. до конца. Его поиск, естественно, снова не увенчивался успехом и на очереди оказывалась подстрока, начиная с третьего символа и т.д. В итоге движку пришлось анализировать 20 000 + 19 999 + 19 998 + … + 1 = 199 990 000 символов!</p><p>Дополнительные пояснения на тему работы регулярный выражений вы можете найти в <a href="https://tproger.ru/translations/regular-expression-python/">нашем</a> руководстве.</p><p><a href="https://web.archive.org/web/20151104105719/http://tproger.ru:80/translations/algorithms-and-data-structures/">Сложность</a> такого действия составляет O(N²) — и хотя, как отмечает автор публикации, это, конечно, не экспоненциальная сложность, но так вышло, что пост-вредитель попал на домашнюю страницу сервиса и вынудил сервера обрабатывать текст регулярным выражением для огромного числа посетителей сервиса, заходящих на него через главную страницу. Это привело к тому, что домашняя страница стала с большими задержками отвечать на запросы. Балансировщик нагрузки Stack Overflow, в свою очередь, оценивает доступность сервиса по доступности домашней страницы, и поэтому воспринял задержку в ответах на запросы как знак того, что работу сервиса необходимо приостановить.</p><p>К слову, исправлена ситуация была очень быстро: 10 минут потребовалось на поиск причины, 14 — на написание кода для ее исправления, и 10 — на внедрение фикса.</p>]]></content:encoded>
    </item>
    <item>
      <title>Лучшие статические анализаторы регулярных выражений</title>
      <link>https://tproger.ru/digest/best-regex-testers</link>
      <comments>https://tproger.ru/digest/best-regex-testers?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Артём Артемьев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/digest/best-regex-testers</guid>
      <description><![CDATA[<p>Регулярные выражения удобны для обработки текста, но написать их с нуля без справочников трудно. Статические анализаторы помогают разобрать сложную регулярку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/digest/best-regex-testers">Лучшие статические анализаторы регулярных выражений</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Подборки]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 17 Oct 2015 12:24:47 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ни для кого не секрет, что регулярные выражения — очень удобный инструмент для решения многих задач, связанных с обработкой текста. Но вряд ли найдется много людей, способных написать любую регулярку с нуля без подсказок, справочников и нескольких (десятков) попыток. Тогда на помощь приходят статические анализаторы регулярных выражений.</p><p>Они бывают совершенно различных форматов: в виде онлайн-ресурса, плагина к IDE или браузеру или в виде самостоятельной программы. Первые удобны для разового или редкого использования. Хотя некоторые онлайн-тестеры имеют возможность сохранения шаблона в виде постоянной ссылки или в аккаунте, для регулярного использования больше подойдут плагины или десктопные приложения.</p><p>Мы выбрали самые интересные приложения из каждой категории. Все заголовки кликабельны.</p><h3>Онлайн-приложения</h3><h4>regex101.com</h4><p>Пожалуй, лучший вариант веб-приложения для разработки регулярных выражений. Поддерживает форматы PCRE (PHP), JavaScript и Python. Есть возможность получить постоянную ссылку на ваш код, сгенерировать код для PHP, JavaScript или Python, создать юнит-тесты, запустить регулярку пошагово и воспользоваться большой библиотекой готовых регулярных выражений.</p><h4>Debuggex</h4><p>Ограничен по функционалу, не поддерживает замену по шаблону. Но взамен предоставляет визуализацию вашего регулярного выражения в виде конечного автомата, что заметно упрощает понимание работы и отладку. Также, как и <a href="https://regex101.com/">regex101.com</a>, поддерживает синтаксис PCRE, JavaScript или Python. Есть платная подписка с расширенными возможностями, такими как оценка производительности или юнит-тесты с просмотром покрытием кода.</p><h4>RegExr 2.0</h4><p>Онлайн-тестер с открытым исходным кодом и приятным дизайном. Хотя по функционалу уступает <a href="https://regex101.com/">regex101.com</a> — только один вариант синтаксиса, нет генерации кода и тестов — для простых задач его вполне достаточно. В отличие от <a href="https://www.debuggex.com/">Debuggex</a>, поддерживает замену по шаблону.</p><h3>Плагины для IDE</h3><h4>Regex Util (IDEA plugin)</h4><p>Плагин для IntelliJ IDEA и других IDE от JetBrains. Минималистичный интерфейс, поддержка замен и разделений по шаблону и всплывающие подсказки с объяснением элементов. Нет возможности сохранения регулярных выражений. Отлично подходит для проверки регулярок перед добавлением в код.</p><h4>Regex Util (Eclipse plugin)</h4><p>Аналог плагина для IntelliJ IDEA с тем же функционалом.</p><h3>Десктопные приложения</h3><h4>Expresso</h4><p>Одна из лучших программ под Windows для написания и проверки регулярных выражений. Огромное количество возможностей: визуальный редактор, генерация кода, библиотека шаблонов. Программа бесплатная, но после 60 дней использования требует регистрации.</p><h4>The Regex Coach</h4><p>Для тех, кому Expresso кажется слишком сложным. Маленькая утилита с возможностью пошагового выполнения регулярного выражения. Поддерживает синтаксис PCRE, который используется в Perl, PHP и очень похож на синтаксис регулярных выражений Java и XML Schema. Программа примечательна тем, что написана на Common Lisp.</p><h4>Regexbuddy</h4><p>Достойный конкурент Expresso с большой библиотекой готовых примеров. Платная ($39.95). Кроме того, на сайте разработчика есть отличные программы <a href="http://www.powergrep.com/">PowerGrep</a> (для сложного поиска по текстовым файлам) и <a href="http://www.regexmagic.com/">RegexMagic</a> (визуальный редактор регулярных выражений).</p><h4>Oyster</h4><p>Платная ($3.99) утилита под OS X. Отличная программа с большим количеством возможностей, интеграцией с <a href="https://kapeli.com/dash">Dash</a> и CodeBox, генерацией кода на Java, JavaScript, Objective-C, Python и других языках.</p><h3>Что выбрать?</h3><p>Если вам необходимо часто писать регулярные выражения для обработки текста или других задач, лучший вариант — самостоятельное приложение вроде <a href="http://www.ultrapico.com/Expresso.htm">Expresso</a> или <a href="http://www.rwe-uk.com/app/oyster">Oyster</a>. Если задача разовая, или вы хотите просто потренироваться, вам помогут онлайн-приложения, такие как <a href="https://regex101.com/">regex101.com</a>. Следует заметить, что список выше далеко не полный, и есть еще много программ, которые помогут вам в вашей работе.</p><p>Кроме того, возможно, вашу задачу кто-то уже решил и поделился решением с сообществом. Обратите внимание на <a href="http://www.regexlib.com/">regexlib.com</a> и <a href="http://www.rexegg.com/">RexEgg</a>.</p>]]></content:encoded>
    </item>
  </channel>
</rss>