HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-21
1 <p><a>#статьи</a></p>
1 <p><a>#статьи</a></p>
2 <ul><li>19 авг 2022</li>
2 <ul><li>19 авг 2022</li>
3 <li>0</li>
3 <li>0</li>
4 </ul><p>Один разработчик выучил все регулярки и был причислен к лику святых.</p>
4 </ul><p>Один разработчик выучил все регулярки и был причислен к лику святых.</p>
5 <p>Иллюстрация: Merry Mary для Skillbox Media</p>
5 <p>Иллюстрация: Merry Mary для Skillbox Media</p>
6 <p>Шеф-редактор Skillbox Media "Код". Пишет о разработке, софт-скиллах и культовых личностях в IT. Обожает Swift, продукты Apple и мемы про код.</p>
6 <p>Шеф-редактор Skillbox Media "Код". Пишет о разработке, софт-скиллах и культовых личностях в IT. Обожает Swift, продукты Apple и мемы про код.</p>
7 <p>Каждый день в интернете появляются гигабайты нового текста: статей, постов, комментариев, сообщений в чатах. Чтобы со всем этим можно было работать с помощью кода, используют регулярные выражения - о них сегодня и поговорим.</p>
7 <p>Каждый день в интернете появляются гигабайты нового текста: статей, постов, комментариев, сообщений в чатах. Чтобы со всем этим можно было работать с помощью кода, используют регулярные выражения - о них сегодня и поговорим.</p>
8 <p>Регулярные выражения - это специальные комбинации символов для поиска и обработки текста. Механика у них простая: вы составляете шаблон слова, которое вам нужно, а программа находит все строки с этим словом. Чтобы искать точнее, для шаблонов можно задавать команды - например, найти все слова без учёта регистра.</p>
8 <p>Регулярные выражения - это специальные комбинации символов для поиска и обработки текста. Механика у них простая: вы составляете шаблон слова, которое вам нужно, а программа находит все строки с этим словом. Чтобы искать точнее, для шаблонов можно задавать команды - например, найти все слова без учёта регистра.</p>
9 <p>Регулярные выражения в JavaScript обычно пишут между двумя наклонными чертами. А сразу за ними идут команды - их называют "флагами".</p>
9 <p>Регулярные выражения в JavaScript обычно пишут между двумя наклонными чертами. А сразу за ними идут команды - их называют "флагами".</p>
10 /регулярное выражение/флаги<p>Внимательный читатель спросит: а чем это отличается от обычной функции "найти и заменить", которая есть в любом "Ворде"? Фишка в том, что можно сочетать регулярки с обычным кодом и обрабатывать любой текст по правилам, менять строки местами, извлекать отдельные слова, передавать информацию на сервер - что угодно.</p>
10 /регулярное выражение/флаги<p>Внимательный читатель спросит: а чем это отличается от обычной функции "найти и заменить", которая есть в любом "Ворде"? Фишка в том, что можно сочетать регулярки с обычным кодом и обрабатывать любой текст по правилам, менять строки местами, извлекать отдельные слова, передавать информацию на сервер - что угодно.</p>
11 <p>Например, можно написать простую форму для оформления рассылки по email - чтобы отклоняла неправильные адреса, а правильные сохраняла в базу.</p>
11 <p>Например, можно написать простую форму для оформления рассылки по email - чтобы отклоняла неправильные адреса, а правильные сохраняла в базу.</p>
12 <p>Работать будет так:</p>
12 <p>Работать будет так:</p>
13 <ul><li>Пользователь заходит на сайт и вводит свой email: dartanyan2mail.ru.</li>
13 <ul><li>Пользователь заходит на сайт и вводит свой email: dartanyan2mail.ru.</li>
14 <li>JavaScript сравнивает адрес с регулярным выражением.</li>
14 <li>JavaScript сравнивает адрес с регулярным выражением.</li>
15 <li>Выясняется, что адрес не совпадает с шаблоном - не хватает знака @.</li>
15 <li>Выясняется, что адрес не совпадает с шаблоном - не хватает знака @.</li>
16 <li>Пользователь получает ошибку и ставит недостающий символ.</li>
16 <li>Пользователь получает ошибку и ставит недостающий символ.</li>
17 </ul><p>Звучит просто, но смотрите, как будет выглядеть регулярное выражение для валидации email-адреса:</p>
17 </ul><p>Звучит просто, но смотрите, как будет выглядеть регулярное выражение для валидации email-адреса:</p>
18 /[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm<p>Когда начинающий программист видит такое, он впадает в ступор, хмурится и уходит дальше писать код, делая вид, что ничего не произошло. Если у вас тоже такая реакция - не переживайте, сейчас будем во всём разбираться.</p>
18 /[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm<p>Когда начинающий программист видит такое, он впадает в ступор, хмурится и уходит дальше писать код, делая вид, что ничего не произошло. Если у вас тоже такая реакция - не переживайте, сейчас будем во всём разбираться.</p>
19 А пока держите мемасик на эту тему<em>Изображение: Telegram-канал "<a>Программисты шутят</a>"</em><p>Настало время разобраться, зачем нужны все эти фигурные скобки, доллары, слэши и прочие эльфийские руны.</p>
19 А пока держите мемасик на эту тему<em>Изображение: Telegram-канал "<a>Программисты шутят</a>"</em><p>Настало время разобраться, зачем нужны все эти фигурные скобки, доллары, слэши и прочие эльфийские руны.</p>
20 <p>Представьте: вы пришли в букинистический магазин, чтобы купить редкое издание "Войны и мира" Льва Толстого 1886 года. Чтобы не копаться в стеллажах самому, скорее всего, вы обратитесь за помощью к продавцу. Продавец знает, где в магазине что лежит, и в два счёта отыщет нужную книгу.</p>
20 <p>Представьте: вы пришли в букинистический магазин, чтобы купить редкое издание "Войны и мира" Льва Толстого 1886 года. Чтобы не копаться в стеллажах самому, скорее всего, вы обратитесь за помощью к продавцу. Продавец знает, где в магазине что лежит, и в два счёта отыщет нужную книгу.</p>
21 <p>В случае с регулярками принцип тот же: вы говорите компьютеру, что нужно найти, задаёте условия, и он ищет. Но загвоздка в том, что машина не понимает слова и предложения: ей подавай простые формальные команды, и чем короче их можно записать, тем меньше памяти всё это будет потреблять.</p>
21 <p>В случае с регулярками принцип тот же: вы говорите компьютеру, что нужно найти, задаёте условия, и он ищет. Но загвоздка в том, что машина не понимает слова и предложения: ей подавай простые формальные команды, и чем короче их можно записать, тем меньше памяти всё это будет потреблять.</p>
22 <p>Один специальный символ означает одно условие поиска. Чем больше условий, тем сложнее будут комбинации символов.</p>
22 <p>Один специальный символ означает одно условие поиска. Чем больше условий, тем сложнее будут комбинации символов.</p>
23 <p>Допустим, у вас есть большая база резюме разработчиков и вы хотите достать оттуда все Telegram-никнеймы. Как это сделать?</p>
23 <p>Допустим, у вас есть большая база резюме разработчиков и вы хотите достать оттуда все Telegram-никнеймы. Как это сделать?</p>
24 <p><strong>Шаг 1.</strong>Найдём все никнеймы формата @username, состоящие из латинских букв. Выражение внутри квадратных скобок означает "любая строчная латинская буква".</p>
24 <p><strong>Шаг 1.</strong>Найдём все никнеймы формата @username, состоящие из латинских букв. Выражение внутри квадратных скобок означает "любая строчная латинская буква".</p>
25 /@[a-z]/<p><strong>Шаг 2.</strong>Добавим в шаблон дефисы, проценты и нижние подчёркивания.</p>
25 /@[a-z]/<p><strong>Шаг 2.</strong>Добавим в шаблон дефисы, проценты и нижние подчёркивания.</p>
26 /@[a-z0-9_-%]/<p><strong>Шаг 3.</strong>Зададим размер слова в символах - если этого не сделать, машина будет выдавать юзернеймы по слогам или отдельным буквам. В нашем случае интервал будет от 5 до 32 символов (такого размера все никнеймы в Telegram).</p>
26 /@[a-z0-9_-%]/<p><strong>Шаг 3.</strong>Зададим размер слова в символах - если этого не сделать, машина будет выдавать юзернеймы по слогам или отдельным буквам. В нашем случае интервал будет от 5 до 32 символов (такого размера все никнеймы в Telegram).</p>
27 /@[a-z0-9_-]{5, 32}/<p><strong>Шаг 4.</strong>Зададим начало и конец фразы, чтобы в выдачу не попали адреса электронной почты. Сделать это можно с помощью символов ^ и $<strong>.</strong></p>
27 /@[a-z0-9_-]{5, 32}/<p><strong>Шаг 4.</strong>Зададим начало и конец фразы, чтобы в выдачу не попали адреса электронной почты. Сделать это можно с помощью символов ^ и $<strong>.</strong></p>
28 /^@[a-z0-9_-%]{5,32}$/g<p><strong>Финальный штрих - флаги.</strong>У регулярок есть странная особенность: по умолчанию алгоритм находит в строке не все совпадения, а только первое. Чтобы это исправить, добавим нашему выражению флаг<strong>g,</strong>который включает глобальный поиск.</p>
28 /^@[a-z0-9_-%]{5,32}$/g<p><strong>Финальный штрих - флаги.</strong>У регулярок есть странная особенность: по умолчанию алгоритм находит в строке не все совпадения, а только первое. Чтобы это исправить, добавим нашему выражению флаг<strong>g,</strong>который включает глобальный поиск.</p>
29 <p>В JavaScript есть и другие флаги: например,<strong>m</strong> - многострочный поиск,<strong>i</strong> - поиск без учёта регистра, а флаг<strong>u</strong>ищет по символам Юникода - например, эмодзи или иероглифам. Как правило, этого набора хватает.</p>
29 <p>В JavaScript есть и другие флаги: например,<strong>m</strong> - многострочный поиск,<strong>i</strong> - поиск без учёта регистра, а флаг<strong>u</strong>ищет по символам Юникода - например, эмодзи или иероглифам. Как правило, этого набора хватает.</p>
30 <p>Была белиберда, а получилась чуть более понятная белиберда. Едем дальше.</p>
30 <p>Была белиберда, а получилась чуть более понятная белиберда. Едем дальше.</p>
31 <p>Сделать это можно двумя способами.</p>
31 <p>Сделать это можно двумя способами.</p>
32 <p><strong>Классический.</strong>Составляем регулярку, оборачиваем её двумя косыми чертами и помещаем в переменную или константу. Потом, если нужно, добавляем флаги. Способ простой, работает почти во всех языках: Java, Python, PHP. C# и так далее. Для большинства задач вам хватит именно его.</p>
32 <p><strong>Классический.</strong>Составляем регулярку, оборачиваем её двумя косыми чертами и помещаем в переменную или константу. Потом, если нужно, добавляем флаги. Способ простой, работает почти во всех языках: Java, Python, PHP. C# и так далее. Для большинства задач вам хватит именно его.</p>
33 var regexp = /шаблон/флаги<p><strong>Через конструктор.</strong>Тут немного посложнее: сначала нужно создать<strong>объект RegExp()</strong>, а уже в него положить регулярное выражение. Причём шаблон и флаги прописывают через запятую, в одинарных кавычках - никаких слэшей.</p>
33 var regexp = /шаблон/флаги<p><strong>Через конструктор.</strong>Тут немного посложнее: сначала нужно создать<strong>объект RegExp()</strong>, а уже в него положить регулярное выражение. Причём шаблон и флаги прописывают через запятую, в одинарных кавычках - никаких слэшей.</p>
34 var regexp = new RegExp('шаблон', 'флаги')<p>Второй способ хорош тем, что позволяет менять выражение на лету, прямо во время исполнения программы. Это удобно, если вы загружаете шаблон из стороннего источника - например, из базы данных.</p>
34 var regexp = new RegExp('шаблон', 'флаги')<p>Второй способ хорош тем, что позволяет менять выражение на лету, прямо во время исполнения программы. Это удобно, если вы загружаете шаблон из стороннего источника - например, из базы данных.</p>
35 <p>Сами по себе регулярные выражения - это просто шаблоны для поиска текста. Чтобы они могли совершать в программе какое-то действие, их надо поместить в функцию. В JavaScript есть два типа функций, которые работают с регулярками:</p>
35 <p>Сами по себе регулярные выражения - это просто шаблоны для поиска текста. Чтобы они могли совершать в программе какое-то действие, их надо поместить в функцию. В JavaScript есть два типа функций, которые работают с регулярками:</p>
36 <ul><li>строковые - базовый набор для обработки любого текста;</li>
36 <ul><li>строковые - базовый набор для обработки любого текста;</li>
37 <li>RegExp-функции - заточенные конкретно под регулярные выражения.</li>
37 <li>RegExp-функции - заточенные конкретно под регулярные выражения.</li>
38 </ul><p><strong>1. search</strong> - простой поиск. Показывает, в каком месте строки есть совпадение с шаблоном. Например, код ниже ищет слово world во фразе "Hello, world!". А так как оно начинается с седьмой буквы, результатом будет "7".</p>
38 </ul><p><strong>1. search</strong> - простой поиск. Показывает, в каком месте строки есть совпадение с шаблоном. Например, код ниже ищет слово world во фразе "Hello, world!". А так как оно начинается с седьмой буквы, результатом будет "7".</p>
39 var str = "Hello, world!"; var regexp = str.search(/world/i);<p><strong>2. match</strong> - найти и показать в виде текста. Тут уже поинтереснее: если функция</p>
39 var str = "Hello, world!"; var regexp = str.search(/world/i);<p><strong>2. match</strong> - найти и показать в виде текста. Тут уже поинтереснее: если функция</p>
40 search<p>просто ищет место в строке, то </p>
40 search<p>просто ищет место в строке, то </p>
41 match<p>находит все слова по шаблону и выдаёт их списком.</p>
41 match<p>находит все слова по шаблону и выдаёт их списком.</p>
42 <p>Допустим, у вас есть какой-то список имён и нужно достать оттуда только те, что написаны на латинице:</p>
42 <p>Допустим, у вас есть какой-то список имён и нужно достать оттуда только те, что написаны на латинице:</p>
43 var names = 'Саша, Carl, Лена, Оля, Sam, Peter, Лев'; console.log(names.match(/[a-zA-Z]{1,10}/gi));<p>Результат будет такой: ['Carl', 'Sam', 'Peter'].</p>
43 var names = 'Саша, Carl, Лена, Оля, Sam, Peter, Лев'; console.log(names.match(/[a-zA-Z]{1,10}/gi));<p>Результат будет такой: ['Carl', 'Sam', 'Peter'].</p>
44 <p><strong>3. replace</strong> - найти и заменить. Позволяет заменить слово целиком или по буквам и слогам. Если копнуть чуть глубже, можно даже менять слова местами в пределах одной фразы:</p>
44 <p><strong>3. replace</strong> - найти и заменить. Позволяет заменить слово целиком или по буквам и слогам. Если копнуть чуть глубже, можно даже менять слова местами в пределах одной фразы:</p>
45 const a = 'Роняет лес багряный свой убор'; const b = str.replace(/(\W+)\s(\W+)\s(\W+)\s(\W+)\s(\W+)/, '$2 $1 $4 $3 $5'); console.log(b);<p><strong>Было:</strong></p>
45 const a = 'Роняет лес багряный свой убор'; const b = str.replace(/(\W+)\s(\W+)\s(\W+)\s(\W+)\s(\W+)/, '$2 $1 $4 $3 $5'); console.log(b);<p><strong>Было:</strong></p>
46 <p>"Роняет лес багряный свой убор".</p>
46 <p>"Роняет лес багряный свой убор".</p>
47 <p><strong>Стало:</strong></p>
47 <p><strong>Стало:</strong></p>
48 <p>"Лес роняет свой багряный убор".</p>
48 <p>"Лес роняет свой багряный убор".</p>
49 <p><strong>4. split</strong> - разбить одну строку на несколько частей. Разделять можно как угодно: хоть по слогам, хоть по буквам, хоть по знакам препинания. Для примера давайте разберём на части какую-нибудь строку из Шекспира:</p>
49 <p><strong>4. split</strong> - разбить одну строку на несколько частей. Разделять можно как угодно: хоть по слогам, хоть по буквам, хоть по знакам препинания. Для примера давайте разберём на части какую-нибудь строку из Шекспира:</p>
50 let message = 'Что есть любовь? Безумье от угара, игра с огнём, ведущая к пожару!'; let sentences = message.split(/[.,!,?]/); console.log(sentences);<p>В итоге получим вот такой набор фраз: ['Что есть любовь', ' Безумье от угара', ' игра с огнём', ' ведущая к пожару', '']. Может, это и бесполезно, зато красиво :)</p>
50 let message = 'Что есть любовь? Безумье от угара, игра с огнём, ведущая к пожару!'; let sentences = message.split(/[.,!,?]/); console.log(sentences);<p>В итоге получим вот такой набор фраз: ['Что есть любовь', ' Безумье от угара', ' игра с огнём', ' ведущая к пожару', '']. Может, это и бесполезно, зато красиво :)</p>
51 <p>Новичкам стоит обратить внимание на два метода RegExp:</p>
51 <p>Новичкам стоит обратить внимание на два метода RegExp:</p>
52 <p><strong>1. test</strong> - проверяет, совпадает ли строка с шаблоном. Если совпадение есть, вернёт</p>
52 <p><strong>1. test</strong> - проверяет, совпадает ли строка с шаблоном. Если совпадение есть, вернёт</p>
53 true<p>, если нет - вернёт</p>
53 true<p>, если нет - вернёт</p>
54 false<p>. Звучит примитивно, но на этой функции работает львиная доля всех форм авторизации в интернете.</p>
54 false<p>. Звучит примитивно, но на этой функции работает львиная доля всех форм авторизации в интернете.</p>
55 <p>Возьмём, например, нашу регулярку для проверки электронной почты. Сама по себе она ничего не проверяет - но если завернуть её в функцию</p>
55 <p>Возьмём, например, нашу регулярку для проверки электронной почты. Сама по себе она ничего не проверяет - но если завернуть её в функцию</p>
56 test<p>, получится надёжная система авторизации - бери и используй.</p>
56 test<p>, получится надёжная система авторизации - бери и используй.</p>
57 var str = "media@skillbox.ru"; var email = (/[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm.test(str)); console.log(email);<p><strong>2. exec</strong> - найти и показать в виде текста. Работает точно так же, как и match, но возвращает только первую найденную строку.</p>
57 var str = "media@skillbox.ru"; var email = (/[A-Z0-9._%+-]+@[A-Z0-9-]+.+.[A-Z]{2,4}/igm.test(str)); console.log(email);<p><strong>2. exec</strong> - найти и показать в виде текста. Работает точно так же, как и match, но возвращает только первую найденную строку.</p>
58 <p>Разберём ещё несколько жизненных ситуаций, в которых могут пригодиться регулярные выражения.</p>
58 <p>Разберём ещё несколько жизненных ситуаций, в которых могут пригодиться регулярные выражения.</p>
59 <p><strong>Проверить почтовый трек-номер.</strong>Допустим, вы делаете чат-бот для отслеживания посылок с AliExpress - чтобы пользователь мог ввести свой трек-номер и узнать, где едет его чехол или браслет. Если брать за основу трек-коды Почты России, регулярное выражение будет выглядеть так:</p>
59 <p><strong>Проверить почтовый трек-номер.</strong>Допустим, вы делаете чат-бот для отслеживания посылок с AliExpress - чтобы пользователь мог ввести свой трек-номер и узнать, где едет его чехол или браслет. Если брать за основу трек-коды Почты России, регулярное выражение будет выглядеть так:</p>
60 /^[0-9]{14}$/<p><strong>Удалить все HTML-теги.</strong>Ситуация: вы спарсили из интернета какой-то текст и хотите очистить его от лишней разметки. Чтобы найти в документе все HTML-теги, используют выражение &lt;.*?&gt;. А для комментариев - &lt;!--(.*?)--&gt;.</p>
60 /^[0-9]{14}$/<p><strong>Удалить все HTML-теги.</strong>Ситуация: вы спарсили из интернета какой-то текст и хотите очистить его от лишней разметки. Чтобы найти в документе все HTML-теги, используют выражение &lt;.*?&gt;. А для комментариев - &lt;!--(.*?)--&gt;.</p>
61 <p><strong>Проверить биткоин-кошелёк.</strong>Допустим, вы настраиваете на сайте оплату в криптовалюте. Чтобы форма принимала только правильные биткоин-адреса, можно использовать вот такой шаблон:</p>
61 <p><strong>Проверить биткоин-кошелёк.</strong>Допустим, вы настраиваете на сайте оплату в криптовалюте. Чтобы форма принимала только правильные биткоин-адреса, можно использовать вот такой шаблон:</p>
62 ^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$<p><strong>Искать в Google.</strong>Знаменитый поисковик поддерживает некоторые возможности регулярок. Например, фраза -Фрэнсис Фицджеральд найдёт всех Фицджеральдов, которых зовут не Фрэнсис. А выражение (gray|red) (wolf|fox) отыщет всех серых волков и рыжих лисиц - и наоборот.<a>Попробуйте</a><a>сами</a>.</p>
62 ^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$<p><strong>Искать в Google.</strong>Знаменитый поисковик поддерживает некоторые возможности регулярок. Например, фраза -Фрэнсис Фицджеральд найдёт всех Фицджеральдов, которых зовут не Фрэнсис. А выражение (gray|red) (wolf|fox) отыщет всех серых волков и рыжих лисиц - и наоборот.<a>Попробуйте</a><a>сами</a>.</p>
63 <em>Скриншот: Skillbox Media</em><p>Чтобы изучить все возможности регулярок, никаких статей не хватит. Если хотите лучше в этом разбираться, почитайте книгу "<a>Регулярные выражения</a>" Джеффри Фридла - это хороший гайд для новичков с понятной теорией и примерами. Или попробуйте бесплатные тренажёры на сайте<a>regexlearn.com</a> - чтобы сразу практиковаться в изученном. Вот хорошая шпаргалка оттуда:</p>
63 <em>Скриншот: Skillbox Media</em><p>Чтобы изучить все возможности регулярок, никаких статей не хватит. Если хотите лучше в этом разбираться, почитайте книгу "<a>Регулярные выражения</a>" Джеффри Фридла - это хороший гайд для новичков с понятной теорией и примерами. Или попробуйте бесплатные тренажёры на сайте<a>regexlearn.com</a> - чтобы сразу практиковаться в изученном. Вот хорошая шпаргалка оттуда:</p>
64 <em>Скриншот: Skillbox Media</em><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
64 <em>Скриншот: Skillbox Media</em><a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>