Знай своего вкуса регулярных выражений
Есть удивительное количество людей, которые думают, что регулярные выражения по существу не зависят от языка. Тем не менее, на самом деле есть довольно существенные различия между разновидностями, и особенно для Code Golf полезно знать некоторые из них и их интересные особенности, так что вы можете выбрать лучшее для каждой задачи. Вот обзор нескольких важных ароматов и того, что отличает их от других. (Этот список не может быть полным, но дайте мне знать, если я пропустил что-то действительно вопиющее.)
Perl и PCRE
Я добавляю их в один банк, так как я не слишком знаком со вкусом Perl, и они в основном эквивалентны (PCRE для Perl-совместимых регулярных выражений в конце концов). Основное преимущество разновидности Perl заключается в том, что вы можете фактически вызывать код Perl из регулярных выражений и подстановок.
- Рекурсия / подпрограммы . Вероятно, самая важная особенность для игры в гольф (которая существует только в нескольких вариантах).
- Условные паттерны
(?(group)yes|no)
.
- Поддерживает изменение в случае замены строки с
\l
, \u
, \L
и \U
.
- PCRE допускает чередование во взглядах, где каждая альтернатива может иметь различную (но фиксированную) длину. (Большинство разновидностей, включая Perl, требуют, чтобы внешний вид имел общую фиксированную длину.)
\G
привязать матч к концу предыдущего матча.
\K
сбросить начало матча
- PCRE поддерживает как свойства символов Unicode, так и сценарии .
\Q...\E
чтобы избежать длинных рядов персонажей. Полезно, когда вы пытаетесь сопоставить строку, которая содержит много метасимволов.
.СЕТЬ
Это, пожалуй, самый мощный аромат, с очень немногими недостатками.
Один важный недостаток с точки зрения игры в гольф состоит в том, что он не поддерживает квантификаторы притяжения, как некоторые другие ароматы. Вместо того, .?+
чтобы вам придется писать (?>.?)
.
Джава
- Из-за ошибки (см. Приложение) Java поддерживает ограниченный тип просмотра с переменной длиной: вы можете смотреть назад до самого начала строки,
.*
откуда вы можете теперь начать просмотр, например (?<=(?=lookahead).*)
.
- Поддерживает объединение и пересечение классов символов.
- Имеет наиболее обширную поддержку Unicode с классами символов для «Unicode-скриптов, блоков, категорий и двоичных свойств» .
\Q...\E
как в Perl / PCRE.
Рубин
В последних версиях этот вариант так же мощен, как и PCRE, включая поддержку вызовов подпрограмм. Как и Java, он также поддерживает объединение и пересечение классов символов. Одна особенность - встроенный класс символов для шестнадцатеричных цифр: \h
(и отрицание \H
).
Самая полезная функция для игры в гольф - это то, как Ruby обрабатывает квантификаторы. В частности, можно вкладывать квантификаторы без скобок. .{5,7}+
работает и так делает .{3}?
. Кроме того, в отличие от большинства других ароматов, если нижняя граница квантификатора равна, 0
она может быть опущена, например .{,5}
, эквивалентна .{0,5}
.
Что касается подпрограмм, основное различие между подпрограммами PCRE в подпрограммах и в Ruby, является то , что синтаксис в Ruby является байты больше (?n)
против \g<n>
, но подпрограммы в Ruby может быть использованы для захвата, в то время как PCRE сбрасывает захваты после того, как подпрограмма заканчивается.
Наконец, в Ruby семантика для модификаторов, связанных с линиями, отличается от большинства других разновидностей. Модификатор, который обычно называют m
другими разновидностями, всегда включен в Ruby. Так ^
и $
всегда соответствует началу и концу линии не только начало и конец строки. Это может сэкономить вам байт, если вам нужно такое поведение, но это будет стоить вам дополнительных байтов, если вы этого не сделаете, потому что вам придется заменить ^
и $
на \A
и \z
, соответственно. В дополнение к этому, модификатор, который обычно вызывается s
(что делает .
совпадение с переводами строки), вызывается m
в Ruby. Это не влияет на количество байтов, но следует помнить, чтобы избежать путаницы.
питон
Python имеет солидный вкус, но я не знаю каких-либо особенно полезных функций, которые вы не найдете больше нигде.
Тем не менее , есть альтернативный вариант, который предназначен для замены re
модуля в какой-то момент, и который содержит много интересных функций. В дополнение к добавлению поддержки рекурсии, видовых объектов переменной длины и операторов комбинации классов символов, он также обладает уникальной функцией нечеткого сопоставления . По сути, вы можете указать ряд ошибок (вставки, удаления, замены), которые допустимы, и механизм также даст вам приблизительные совпадения.
ECMAScript
Вкус ECMAScript очень ограничен и, следовательно, редко очень полезен для игры в гольф. Единственное, что у него получается, это отрицательный класс пустых символов, [^]
соответствующий любому символу, а также безоговорочно провальный класс пустых символов []
(в отличие от обычного (?!)
). К сожалению, аромат не имеет каких-либо особенностей, которые делают последний полезным для нормальных проблем.
Lua
У Lua есть свой собственный довольно уникальный вкус, который весьма ограничен (например, вы не можете даже количественно определить группы), но имеет несколько полезных и интересных функций.
- Он имеет большое количество сокращений для встроенных классов символов , включая знаки пунктуации, символы верхнего / нижнего регистра и шестнадцатеричные цифры.
- С
%b
его помощью поддерживается очень компактный синтаксис для сопоставления сбалансированных строк. Например, %b()
соответствует a, (
а затем все до совпадения )
(правильно пропуская внутренние совпадающие пары). (
и )
может быть любые два символа здесь.
Увеличение
Регулярный вкус Boost по сути Perl. Тем не менее, у него есть несколько приятных новых возможностей для подстановки регулярных выражений, включая изменения регистра и условия . Последнее, насколько я знаю, уникально для Boost.