Мне нравятся разделители %r<…>
, потому что с их помощью действительно легко определить начало и конец регулярного выражения, и мне не нужно избегать каких-либо /
. Но кажется, что у них есть непреодолимое ограничение, которого нет у других разделителей?
Все остальные мыслимые разделители работают нормально:
/(?<!foo)/
%r{(?<!foo)}
%r[(?<!foo)]
%r|(?<!foo)|
%r/(?<!foo)/
Но когда я пытаюсь сделать это:
%r<(?<!foo)>
выдает синтаксическую ошибку:
unterminated regexp meets end of file
Ладно, возможно, ему не нравится, что это не сбалансированная пара, но как вы можете избежать этого так, чтобы понравилось ?
Нужно ли что-нибудь избежать?
Согласно wikibooks.org :
В качестве разделителя можно использовать любой отдельный не буквенно-цифровой символ,
%[including these], %?or these?, %~or even these things~
.
Используя это обозначение, могут появиться обычные разделители строк "и"
в строке unescaped, но, конечно, новый разделитель, который вы выбрали
нужно сбежать.
Действительно, экранирование необходимо в следующих примерах:
%r!(?<\!foo)!
%r?(\?<!foo)?
Но если бы это была единственная проблема, тогда я мог бы уйти от этого и заставить это работать:
%r<(?\<!foo)>
Но это приводит к этой ошибке:
undefined group option: /(?\<!foo)/
Так, может быть, экранирование не необходимо / разрешено? wikibooks.org перечисляет %<pointy brackets>
как одно из исключений:
Однако, если вы используете
%(parentheses), %[square brackets], %{curly brackets}
или
%<pointy brackets>
как разделители, так и те же разделители
может отображаться в строке без экранирования , если они находятся в сбалансированном
пар
Это проблема с сбалансированными парами?
Сбалансированные пары - не проблема, если вы делаете что-то в регулярном выражении, которое требует их, например ...
%r{(?<!foo{1})} # repetition quantifier
%r[(?<![foo])] # character class
%r<(?<name>foo)> # named capture group
Но что если вам нужно вставить разделитель слева ({, [или <) внутри регулярного выражения? Просто избегай этого, верно? В Ruby, похоже, нет проблем с экранированными несбалансированными разделителями <em>в большинстве случаев ...
%r{(?<!foo\{)}
%r[(?<!\[foo)]
%r<\<foo>
Это просто когда вы пытаетесь сделать это в середине «опций группы» (что, я думаю, означает то, что символы <!
классифицируются как здесь) после (?
, ему это не нравится:
%r<(?\<!foo)>
# undefined group option: /(?\<!foo)/
Так как же вы тогда делаете это и делаете Руби счастливым? (без изменения разделителей)
Заключение
Обойти это легко. Я просто изменю это регулярное выражение, чтобы вместо него использовать что-то другое, например %r{…}
.
Но вопросы остаются ...
- Неужели нет способа убежать от
<
здесь?
- Действительно ли есть регулярные выражения, которые просто невозможно написать, используя определенные разделители, такие как
%r<…>
?
- Является
%r<…>
единственной парой регулярных выражений, которая имеет эту проблему (где некоторые регулярные выражения невозможно записать при ее использовании). Если вам известен подобный пример с %r{…}
/ %r[…]
, поделитесь!
Информация о версии
Не то чтобы это, вероятно, имеет значение, поскольку этот синтаксис, вероятно, не изменился, но я использую:
⟫ ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-linux]
Справка: