Какие символы в сочетании с ^ не нужно экранировать в sed?

Я проверил это ^* а также ^& линии соответствия начинаются с * а также &что я не сделал, так как они являются специальными персонажами. Но ^[ не работает Это "стандартное" поведение? Есть ли какое-либо объяснение этому?

sed использовалась версия "GNU sed 4.4".

2 ответа

Решение

От POSIX.1-2017:

Утилита sed должна поддерживать BRE, описанные в Основных регулярных выражениях XBD,... [ sed ]

Читая раздел POSIX о BRE, мы читаем:

Специальный символ BRE обладает особыми свойствами в определенных контекстах. Вне этих контекстов или когда перед ним стоит <обратный слэш>, такой символ является BRE, который соответствует самому специальному символу. Специальные символы BRE и контексты, в которых они имеют свое особое значение, следующие:

  • .[\ : , > и должны быть специальными, за исключением случаев, когда они используются в выражении в скобках (см. RE Bracket Expression). Выражение, содержащее '[', которое не экранировано и не является частью выражения в скобках, дает неопределенные результаты.
  • * : <Звездочка> должна быть особенной, кроме случаев, когда она используется:
    • В выражении в скобках
    • Как первый символ всего BRE (после начального '^', если есть)
    • В качестве первого символа подвыражения (после начального '^', если есть); см. BRE, соответствующие нескольким символам
  • ^ : должен быть особенным при использовании в качестве якоря (см. BRE Expression Anchoring). должен обозначать несоответствующее выражение списка, когда оно встречается первым в списке, сразу после <левой квадратной скобки> (см. RE Bracket Expression).
  • $ : <Знак доллара> должен быть особенным при использовании в качестве якоря.

источник: основные регулярные выражения, специальные символы

Таким образом, чтобы ответить на вопрос ОП, используя выше:

  • & это не специальный символ, так ^& как ожидается, будет работать
  • [ всегда должен быть экранирован, если он не используется в качестве выражения в скобках.
  • * не является особенным после начального ^ когда последний является якорем.

Таким образом, все наблюдаемые заявления ОП являются действительными.

Однако в RE Bracket Expression есть еще интересный параграф:

Выражение в скобках - это либо совпадающее выражение списка, либо несовпадающее выражение списка. Он состоит из одного или нескольких выражений: обычных символов, элементов сопоставления, символов сопоставления, классов эквивалентности, классов символов или выражений диапазона. <Правая квадратная скобка> ( ] ) теряет свое специальное значение и представляет себя в выражении в скобках, если оно встречается первым в списке (после начального ( ^ ), если есть). В противном случае оно должно заканчиваться выражением в скобках, если только оно не появляется в сопоставляющем символе (таком как [.].] ) или является окончанием <правая квадратная скобка> для сопоставляющего символа, класса эквивалентности или класса символов. Специальные символы ., *, [, а также \\ (<точка>, <звездочка>, <левая квадратная скобка> и <обратная косая черта> соответственно) теряют свое особое значение в выражении в скобках.

источник: Базовые регулярные выражения, выражение в скобках RE

Это подразумевает, что ] не может быть экранирован в выражении в скобках. Это означает:

Следующая работа:

$ echo '[]' | sed 's/[^]x]/a/'
a]
$ echo '[]' | sed 's/[^x[.].]]/a/'
a]

но это не работает, как ожидалось:

$ echo '[]' | sed 's/[^x\]]/a/'
[]

Так что в выражении в скобках не избегайте этого, а сопоставляйте!

Увидеть sed "3.3. Обзор синтаксиса регулярных выражений".

& char не является специальным регулярным выражением char, ему не нужно экранировать в регулярном выражении. Обратите внимание, что & может быть проанализирован как специальная конструкция в шаблоне замены, где это относится ко всему совпадению.

* не является особенным, когда это в начале в GNU sed (^* это шаблон, который соответствует * в начале строки):

POSIX 1003.1-2001 говорит, что * выступает за себя, когда он появляется в начале регулярного выражения или подвыражения, но многие реализации не-GNU не поддерживают это, и вместо этого переносимые сценарии должны использовать \* в этих контекстах.

[ запускает выражение в скобках и должно иметь пару ] закрыть выражение, следовательно, это ошибка.

Другие вопросы по тегам