Диалекты: Python vs JavaScript vs grep

Понимаем, что «регулярки везде одинаковые» — только на 90%, и где прячутся оставшиеся 10%.

Базовый синтаксис (. * + ? [] () |, классы \d \w \s) совпадает почти везде; различия — в группах, проверках, флагах и экранировании.

Что общего

Хорошая новость: ядро одинаково во всех популярных диалектах. Точка, кванторы, классы символов, готовые классы \d \w \s, якоря ^ $, группы и альтернация работают так же, как мы изучали. Освоив Python-регулярки, вы прочитаете паттерн в JavaScript, Java или Go почти без переучивания.

Python и JavaScript: близнецы с нюансами

АспектPythonJavaScript
именованная группа(?P<name>...)(?<name>...)
ссылка в замене\1, \g<name>$1, $<name>
флаг «все совпадения»есть findallфлаг g на регулярке
lookbehindфиксированной длиныпеременной длины (совр. движки)

Например, замена даты. В Python ссылки на группы — \1:

import re
print(re.sub(r"(\d{4})-(\d{2})", r"\2/\1", "2024-06"))

Вывод:

06/2024

А в JavaScript тот же смысл записали бы как str.replace(/(\d{4})-(\d{2})/, "$2/$1") — ссылки через $1, $2. Логика одна, синтаксис подстановки разный.

grep: два режима

В командной строке grep по умолчанию использует базовые регулярки (BRE), где +, ?, {}, () и | нужно экранировать обратным слэшем: \(, \+. Расширенный режим (grep -E или egrep) делает их обычными метасимволами — как мы привыкли:

# базовый grep — скобки и плюс экранируют
grep '\(ab\)\+' file.txt
# расширенный — как в Python
grep -E '(ab)+' file.txt

Поэтому, копируя паттерн из туториала в grep, добавляйте -E — иначе скобки и кванторы поймут буквально.

Главные точки расхождения

  • Синтаксис именованных групп и ссылок в замене — он разный (см. таблицу).
  • Флаги: где-то это аргумент функции (Python), где-то буква на самой регулярке (JS: /.../gi).
  • Экранирование в shell: в grep/sed ещё и оболочка обрабатывает кавычки — паттерны берут в одинарные кавычки.
  • Поддержка lookbehind и продвинутых конструкций отличается между движками.

Итог

  • Ядро регулярок одинаково во всех языках — навык переносится.
  • Различаются: именованные группы, ссылки в замене (\1 vs $1), способ задания флагов.
  • grep по умолчанию — базовый синтаксис; для привычного берите grep -E.
  • Перенося паттерн в новую среду, сверяйтесь с её документацией по этим точкам.
Проверьте себя
1. Как в Python и в JavaScript различается ссылка на первую группу в строке-замене?
AВезде \1
BВ Python — \1, в JavaScript — $1
CВезде $1
DСсылки на группы в замене невозможны
2. Почему паттерн (ab)+ может не сработать в обычном grep?
Agrep не поддерживает регулярки
BВ базовом синтаксисе grep скобки и + нужно экранировать; нужен grep -E (расширенный режим)
CНужен флаг IGNORECASE
Dgrep работает только с цифрами
3. Что в большинстве диалектов регулярок РАБОТАЕТ одинаково?
AСинтаксис именованных групп
BБазовое ядро: точка, кванторы, классы [...], \d \w \s, якоря ^ $, альтернация
CСпособ задания флагов
DСинтаксис ссылок в замене
Поддержать проект