Регулярные выражения предоставляют декларативный язык для сопоставления шаблонов в строках. Они обычно используются для проверки, синтаксического анализа и преобразования строк. Поскольку регулярные выражения не полностью стандартизированы, все вопросы с этим тегом должны также включать тег, определяющий применимый язык программирования или инструмент. ПРИМЕЧАНИЕ. Запрос регулярных выражений HTML, JSON и т. Д. Обычно вызывает отрицательную реакцию. Если для этого есть парсер, используйте его.

ВАЖНОЕ ПРИМЕЧАНИЕ. Запросы на объяснение шаблона или конструкции регулярного выражения будут закрыты как дубликаты канонического сообщения " Что означает это регулярное выражение", в котором содержится много деталей о конструкциях регулярных выражений. Сообщение также содержит ссылки на многие популярные онлайн-тестеры регулярных выражений (где можно найти значения конструкций регулярных выражений). Один из таких инструментов - Regex101.


Регулярные выражения - мощный формализм для сопоставления с образцом в строках. Они доступны на различных диалектах (также известных как разновидности) в ряде языков программирования и в инструментах обработки текста, а также во многих специализированных приложениях. Термин "Регулярное выражение" обычно сокращается до "RegEx" или "regex".

Прежде чем задать здесь вопрос, пожалуйста, уделите время и ознакомьтесь со следующими краткими рекомендациями.

Как спросить

  • Четко сформулируйте, что вам нужно.

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

    Кроме того, вы ищете регулярное выражение для проверки ввода (которое должно быть довольно строгим) или оно вам нужно для извлечения информации (что может быть несколько упрощено)?

    Если ваш вопрос относится к регулярным выражениям в строгом смысле информатики / теории автоматов, просьба указать это явно.

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

  • Покажи нам, что ты пробовал.

    Ссылка на один из многих онлайн-инструментов тестирования регулярных выражений (см. Раздел ссылок) с вашей попыткой и некоторыми репрезентативными данными может творить чудеса.

    Даже если вы не можете опубликовать свою проблему в Интернете, показ ваших лучших попыток поможет нам сосредоточиться на том, с чем вам нужна помощь.

  • Ищите дубликаты.

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

Избегайте общих проблем и ловушек

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

    Хотя современная поддержка регулярных выражений Perl/Ruby/Python/PHP/Java широко распространена, вы не можете предполагать, что она универсальна. В частности, многие старые инструменты (AWK,sed, grep, lexи т. д.), а также некоторые более новые (JavaScript, многие текстовые редакторы) используют разные диалекты, некоторые из которых не обязательно поддерживают, например, скобки без захвата (?:...), не жадные кванторы *?, обратные ссылки (\1, \2и т. д.), сокращения классов общих символов (\t, \d, Классы символов POSIX [[:class:]]), произвольное повторение {m,n}, прогноз (?=...), (?<=...), (?!...)и т. д. и т. д.

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

  • Поймите разницу между "глобальными" выражениями и настоящими регулярными выражениями.

    Шаблоны глобуса - менее эффективный язык сопоставления шаблонов, который обычно используется для подстановочных знаков имен файлов. В глобусе* означает "что угодно", в то время как одинокий * в регулярном выражении на самом деле является синтаксической ошибкой в ​​некоторых диалектах (хотя многие движки будут игнорировать ее, а не выдавать предупреждение; а другие все равно будут рассматривать ее как буквальный *).

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

    См. Также В чем разница между шаблоном стиля глобуса и регулярным выражением?

  • Указывать одно повторение не нужно.

    С помощью {1}поскольку квантификатор однократного повторения безвреден, но бесполезен. По сути, это признак неопытности и / или растерянности.

    h{1}t{1}t{1}p{1} соответствует той же строке, что и более простое выражение http (или ht{2}p если на то пошло), но, как видите, избыточный {1} повторения только затрудняют чтение.

  • Квадратные скобки обычно неправильно понимают или используют неправильно.

    Новички часто пытаются использовать квадратные скобки для всего, включая группировку. Пока[Jun][Jul]может выглядеть как регулярное выражение для соответствующих месяцев, на самом деле оно соответствуетJJ, Ju, Jl, uJ, uu, ul, nJ, nu, или nl; неJun или Jul. [Jun|Jul] это расточительный способ написать функционально идентичный [|Junl]- соответствует любому символу из набора, включающего |, J, u, l, а также n.

    Для записи, [abc]определяет класс символов, который соответствует одному символу, который может бытьa или b или c. Правильный способ выразить чередование:(Jun|Jul|Aug)во многих диалектах (хотя BRE и родственные диалекты требуют обратной косой черты;\(Jun\|Jul\|Aug\) для традиционных grep и др.) или, несколько более экономно, (Ju[nl]|Aug)

  • Отрицание сложно.

    Как и в предыдущем случае, новички будут использовать классы отрицательных символов, чтобы попытаться ограничить то, что может быть сопоставлено. Например, чтобы соответствоватьturn но нет turned, следующее не делает того, что вы хотите: turn[^ed] - будет соответствовать turn за которым следует любой одиночный символ, который не e или d (так что это не будет соответствовать turner, например).

    Фактически, традиционное регулярное выражение не позволяет легко выразить это. С ERE вы могли бы сказатьturn($|[^e]|e$|e[^d]) чтобы сказать это turn не может следовать ничего, или символ, который не e, или e если не по очереди d. Современные диалекты регулярных выражений имеют расширение под названием lookarounds, которое позволяет вам сказатьturn(?!ed)- но прежде чем двигаться дальше, убедитесь, что ваш инструмент поддерживает этот синтаксис.

    Также обратите внимание, как оператор отрицания класса символов отличается от начала привязки строки (^[abc] совпадения a, b, или c в начале строки, тогда как [^abc] соответствует одному символу, который не a, b, или c).

    См. Также следующий пункт.

  • Если есть способ сопоставления, двигатель его найдет.

    Распространенная ошибка новичков - предоставлять бесполезные необязательные ведущие или замыкающие элементы. В концеs? в dogs? ничего не делает, чтобы предотвратить матч на doggone или endogenous. Если вы хотите предотвратить это, вам нужно будет уточнить - возможно, что-то вродеdogs?\> (при условии, что ваш диалект поддерживает оператор границы последнего слова и при условии, что вы это имеете в виду).

    Как бы то ни было, регулярное выражение dogs? будет соответствовать точно таким же строкам, как и просто dog (хотя, если ваше приложение фиксирует совпадение, только первое будет фиксировать конечный s если есть).

  • Матчи жадные.

    Регулярное выражение a.*b будет соответствовать всей строке "abbbbbb", потому что *всегда будет соответствовать в максимально возможной степени. Сказатьa[^ab]*b если это то, что вы имеете в виду, или используйте нежадное сопоставление, если ваш диалект это поддерживает.

  • Смотрите, что вы снимаете

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

    Также, в частности, следите за (abc){2,3}который фиксирует только последнее вхождениеabcв согласованной строке. Если вы хотите, чтобы повторение было частью захвата, оно должно быть внутри круглых скобок, например:((abc){2,3})

  • Не используйте регулярное выражение для всего!

    В частности, использование (обычно ориентированных на строки) традиционных инструментов регулярных выражений для обработки структурированных форматов, таких как HTML, XML, JSON, файлов конфигурации с блочной структурой (Apache, nginx, многие серверы имен и т. Д.), Скорее всего, не сработает или приведет к неправильному приводит к многочисленным угловым случаям.

    Запрос регулярных выражений HTML обычно вызывает отрицательную реакцию. Обоснование распространяется на все структурированные форматы. Если для этого есть парсер, используйте его.

Дальнейшее чтение

Изучение регулярных выражений

Книги

Документация по JavaScript

Онлайн-песочницы (для тестирования и публикации регулярных выражений в Интернете)

Онлайн-генератор регулярных выражений (для построения регулярных выражений с помощью упрощенного ввода)

Прочие ссылки

Regex использует:

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

Хотя регулярные выражения могут быть полезны в поисковых системах Интернета, их обработка по всей базе данных может потреблять чрезмерные ресурсы компьютера в зависимости от сложности и структуры регулярного выражения. Хотя во многих случаях системные администраторы могут выполнять внутренние запросы на основе регулярных выражений, большинство поисковых систем не предлагают публичной поддержки регулярных выражений. Примечательные исключения: searchcode или ранее использовавшийся поиск Google Code, который был закрыт в 2012 году.
Google также предлагает re2 (C++ - быстрая, безопасная, ориентированная на потоки альтернатива движкам с обратным отслеживанием регулярных выражений, подобным тем, которые используются в PCRE, Perl и Python): он не выполняет обратный ход и гарантирует линейный рост времени выполнения с увеличением размера ввода.