Можно ли указать группы, не участвующие в sed?
если да, то как?
Можно ли указать группы, не участвующие в sed?
если да, то как?
Ответ заключается в том, что с момента написания вы не можете - sed не поддерживает его. Sed поддерживает BRE и ERE, но не PCRE.
(Примечание. Один ответ указывает, что BRE также известен как POSIX sed, а ERE - расширение GNU через sed -r. Точка остается, что PCRE не поддерживается sed.)
Perl будет работать, для Windows или Linux
примеры здесь
https://superuser.com/questions/416419/perl-for-matching-with-regular-expressions-in-terminal
Существует программа, хотя и для Windows, которая может выполнять поиск и замену в командной строке и поддерживает PCRE. Он называется rxrepl. Конечно, это не так, но он ищет и заменяет поддержку PCRE.
C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(c)" -r "\1"
a
C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(c)" -r "\3"
c
C:\blah\rxrepl>echo abc | rxrepl -s "(a)(b)(?:c)" -r "\3"
Invalid match group requested.
C:\blah\rxrepl>echo abc | rxrepl -s "(a)(?:b)(c)" -r "\2"
c
C:\blah\rxrepl>
Автор (а не я) упомянул о своей программе в ответе здесь https://superuser.com/questions/339118/regex-replace-from-command-line
Он имеет действительно хороший синтаксис.
Стандартной вещью для использования будет perl или почти любой другой язык программирования, который люди используют.
Круглые скобки могут использоваться для группировки альтернатив. Например:
sed 's/a\(bc\|de\)f/X/'
говорит заменить "abcf" или "adef" на "X", но скобки также фиксируются. В sed
нет объекта для такой группировки без захвата. Если у вас есть сложное регулярное выражение, которое выполняет как альтернативную группировку, так и захват, вам просто нужно быть осторожным при выборе правильной группы захвата в вашей замене.
Возможно, вы могли бы сказать больше о том, что именно вы пытаетесь выполнить (что вам нужно для групп, не участвующих в захвате), и почему вы хотите избежать групп захвата.
Edit:
Существует тип не захватывающих скобок ((?:pattern)
), которые являются частью Perl-совместимых регулярных выражений (PCRE). Они не поддерживаются в sed
(но при использовании grep -P
).
Я предполагаю, что вы говорите о синтаксисе backrefence, который представляет собой круглые скобки ( )
не скобки [ ]
По умолчанию sed
будет интерпретировать ( )
буквально и не пытаться сделать из них бэкредфенс. Вам нужно будет сбежать от них, чтобы сделать их особенными, как в \( \)
. Только когда вы используете опцию GNU sed -r
, экранирование будет отменено. С помощью sed -r
неэкранный ( )
будет создавать обратные ссылки, а escape-код \( \)
будет рассматриваться как литерал. Примеры:
sed
$ echo "foo(###)bar" | sed 's/foo(.*)bar/@@@@/'
@@@@
$ echo "foo(###)bar" | sed 's/foo(.*)bar/\1/'
sed: -e expression #1, char 16: invalid reference \1 on `s' command RHS
-bash: echo: write error: Broken pipe
$ echo "foo(###)bar" | sed 's/foo\(.*\)bar/\1/'
(###)
sed -r
$ echo "foo(###)bar" | sed -r 's/foo(.*)bar/@@@@/'
@@@@
$ echo "foo(###)bar" | sed -r 's/foo(.*)bar/\1/'
(###)
$ echo "foo(###)bar" | sed -r 's/foo\(.*\)bar/\1/'
sed: -e expression #1, char 18: invalid reference \1 on `s' command RHS
-bash: echo: write error: Broken pipe
Из комментариев:
Групповые, не захватывающие скобки ( )
, поэтому вы можете использовать что-то вроде интервалов {n,m}
без создания обратной ссылки \1
не существует. Во-первых, интервалы не относятся к POSIX sed, вы должны использовать расширение GNU -r
, чтобы включить их. Как только вы включите -r
, любые скобки для группировки также будут захвачены для использования в обратном направлении. Примеры:
$ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###/'
###789
$ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###\1/'
###456.789